类的成员函数内部声明另一个类是什么语法

sun_li3 2020-03-19 04:35:22
类Message的成员函数内部声明了另一个类ReflectiveFieldParser ;
const char* Message::_InternalParse(const char* ptr,
internal::ParseContext* ctx) {
class ReflectiveFieldParser {
public:
ReflectiveFieldParser(Message* msg, internal::ParseContext* ctx)
: ReflectiveFieldParser(msg, ctx, false) {}

void AddVarint(uint32 num, uint64 value) {
if (is_item_ && num == 2) {
if (!payload_.empty()) {
auto field = Field(value, 2);
if (field && field->message_type()) {
auto child = reflection_->MutableMessage(msg_, field);
// TODO(gerbens) signal error
child->ParsePartialFromString(payload_);
} else {
MutableUnknown()->AddLengthDelimited(value)->swap(payload_);
}
return;
}
type_id_ = value;
return;
}
auto field = Field(num, 0);
if (field) {
SetField(value, field, msg_, reflection_);
} else {
MutableUnknown()->AddVarint(num, value);
}
}
void AddFixed64(uint32 num, uint64 value) {
auto field = Field(num, 1);
if (field) {
SetField(value, field, msg_, reflection_);
} else {
MutableUnknown()->AddFixed64(num, value);
}
}
const char* ParseLengthDelimited(uint32 num, const char* ptr,
internal::ParseContext* ctx) {
if (is_item_ && num == 3) {
if (type_id_ == 0) {
return InlineGreedyStringParser(&payload_, ptr, ctx);
}
num = type_id_;
type_id_ = 0;
}
auto field = Field(num, 2);
if (field) {
return ParseLenDelim(num, field, msg_, reflection_, ptr, ctx);
} else {
return InlineGreedyStringParser(
MutableUnknown()->AddLengthDelimited(num), ptr, ctx);
}
}
const char* ParseGroup(uint32 num, const char* ptr,
internal::ParseContext* ctx) {
if (!is_item_ && descriptor_->options().message_set_wire_format() &&
num == 1) {
is_item_ = true;
ptr = ctx->ParseGroup(this, ptr, num * 8 + 3);
is_item_ = false;
type_id_ = 0;
return ptr;
}
auto field = Field(num, 3);
if (field) {
auto msg = GetGroup(num, field, msg_, reflection_);
return ctx->ParseGroup(msg, ptr, num * 8 + 3);
} else {
return UnknownFieldParse(num * 8 + 3, MutableUnknown(), ptr, ctx);
}
}
void AddFixed32(uint32 num, uint32 value) {
auto field = Field(num, 5);
if (field) {
SetField(value, field, msg_, reflection_);
} else {
MutableUnknown()->AddFixed32(num, value);
}
}

const char* _InternalParse(const char* ptr, internal::ParseContext* ctx) {
// We're parsing the a MessageSetItem
GOOGLE_DCHECK(is_item_);
return internal::WireFormatParser(*this, ptr, ctx);
}

private:
Message* msg_;
const Descriptor* descriptor_;
const Reflection* reflection_;
internal::ParseContext* ctx_;
UnknownFieldSet* unknown_ = nullptr;
bool is_item_ = false;
uint32 type_id_ = 0;
std::string payload_;

ReflectiveFieldParser(Message* msg, internal::ParseContext* ctx,
bool is_item)
: msg_(msg),
descriptor_(msg->GetDescriptor()),
reflection_(msg->GetReflection()),
ctx_(ctx),
is_item_(is_item) {
GOOGLE_CHECK(descriptor_) << msg->GetTypeName();
GOOGLE_CHECK(reflection_) << msg->GetTypeName();
}

const FieldDescriptor* Field(int num, int wire_type) {
auto field = descriptor_->FindFieldByNumber(num);

// If that failed, check if the field is an extension.
if (field == nullptr && descriptor_->IsExtensionNumber(num)) {
const DescriptorPool* pool = ctx_->data().pool;
if (pool == nullptr) {
field = reflection_->FindKnownExtensionByNumber(num);
} else {
field = pool->FindExtensionByNumber(descriptor_, num);
}
}
if (field == nullptr) return nullptr;

if (internal::WireFormat::WireTypeForFieldType(field->type()) !=
wire_type) {
if (field->is_packable()) {
if (wire_type ==
internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
return field;
}
}
return nullptr;
}
return field;
}

UnknownFieldSet* MutableUnknown() {
if (unknown_) return unknown_;
return unknown_ = reflection_->MutableUnknownFields(msg_);
}
};

ReflectiveFieldParser field_parser(this, ctx);
return internal::WireFormatParser(field_parser, ptr, ctx);
}

代码是protobuf-master 里面的,src/google/protobuf/message.cc line_377---line_518,之前没见过这样的c++语法。
...全文
172 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
sun_li3 2020-03-26
  • 打赏
  • 举报
回复
引用 11 楼 qybao 的回复:
函数内也可以啊,类是一种类型,跟结构体一样。在函数内定义的类只在函数内可见 for example
int main(int argc, const char * argv[]) {
    class MA { 
    public :
        MA() {printf("create...\n");}
        ~MA() {printf("delete...\n");}
    };
    MA ma;
    return 0;
}
有道理,是这个意思
qybao 2020-03-26
  • 打赏
  • 举报
回复
函数内也可以啊,类是一种类型,跟结构体一样。在函数内定义的类只在函数内可见
for example
int main(int argc, const char * argv[]) {
class MA {
public :
MA() {printf("create...\n");}
~MA() {printf("delete...\n");}
};
MA ma;
return 0;
}
sun_li3 2020-03-26
  • 打赏
  • 举报
回复
引用 6 楼 qybao 的回复:
补充,命名空间可以嵌套 a::b::c a和b都是命名空间,b在a的命名空间里,c是函数或变量
命名空间我还是稍微了解的,可这里Message 不是命名空间是类,internal才是命名空间 namespace google { namespace protobuf { namespace internal { 代码中命名空间嵌套,我知道, 我想问的是: 函数内 可以实现类的声明和实现吗? 没见过这个语法 class ReflectiveFieldParser ---这很明显是类呀
sun_li3 2020-03-26
  • 打赏
  • 举报
回复
引用 7 楼 帅得不敢出门 的回复:
限定作用域 。
类在函数内部实现 是为了限定作用域?
sun_li3 2020-03-26
  • 打赏
  • 举报
回复
引用 5 楼 qybao 的回复:
::前面是命名空间,后面是在该命名空间里定义的函数或变量
大哥看清楚点呀, 类的成员函数实现也是这样的,Message是类
帅得不敢出门 2020-03-25
  • 打赏
  • 举报
回复
限定作用域 。
qybao 2020-03-25
  • 打赏
  • 举报
回复
补充,命名空间可以嵌套 a::b::c a和b都是命名空间,b在a的命名空间里,c是函数或变量
qybao 2020-03-25
  • 打赏
  • 举报
回复
::前面是命名空间,后面是在该命名空间里定义的函数或变量
sun_li3 2020-03-25
  • 打赏
  • 举报
回复
引用 2 楼 qybao 的回复:
那是命名空间,可以使用using来省略 比如std命名空间的函数 std::max(5, 6); //带命名空间的方式 using namespace std; max(5,6); //省略命名空间的方式
大牛,说清楚点,对照上面的代码说呀
sun_li3 2020-03-25
  • 打赏
  • 举报
回复
引用 1 楼 suifengsanjin 的回复:
參考名字空間namespace
请问哪个是名字空间? Message吗
qybao 2020-03-19
  • 打赏
  • 举报
回复
那是命名空间,可以使用using来省略
比如std命名空间的函数
std::max(5, 6); //带命名空间的方式

using namespace std;
max(5,6); //省略命名空间的方式
  • 打赏
  • 举报
回复
參考名字空間namespace

64,639

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧