0
点赞
收藏
分享

微信扫一扫

C#描述-计算机视觉OpenCV(5):直方图算法

目录


1.Any类型

1.说明

  • 字段还可以声明为Any类型,可以理解为泛型类型
    • 使⽤时可以在Any存储任意消息类型
      • 父类是Message
    • Any类型的字段也可以⽤repeated来修饰
  • Any类型是Google已经定义好的类型,其中的include⽬录下查找所有Google已经定义好的.proto⽂件
    • 以我的机器为例ls /usr/include/google/protobuf

2.代码&使用

  • .proto文件
    syntax = "proto3";
    package contacts;

    import "google/protobuf/any.proto"; // 引⼊ any.proto ⽂件

    message Address
    {
    string home_address = 1;
    string unit_address = 2;
    }

    message PeopleInfo
    {
    string name = 1;
    int32 age = 2;
    message Phone
    {
    string number = 1;
    enum PhoneType
    {
    MP = 0;
    TEL = 1;
    }
    PhoneType type = 2;
    }
    repeated Phone phone = 3;
    google.protobuf.Any data = 4;
    }

    message Contacts
    {
    repeated PeopleInfo contacts = 1;
    }
  • 编译生成的CPP代码
    // 新⽣成的 Address 类
    class Address final : public ::PROTOBUF_NAMESPACE_ID::Message 
    {
    public:
        using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
        void CopyFrom(const Address& from);
        using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
        void MergeFrom( const Address& from) 
        {
        Address::MergeImpl(*this, from);
        }
    
        // string home_address = 1;
        void clear_home_address();
        const std::string& home_address() const;
        template <typename ArgT0 = const std::string&, typename... ArgT>
        void set_home_address(ArgT0&& arg0, ArgT... args);
        std::string* mutable_home_address();
        PROTOBUF_NODISCARD std::string* release_home_address();
        void set_allocated_home_address(std::string* home_address);
    
        // string unit_address = 2;
        void clear_unit_address();
        const std::string& unit_address() const;
        template <typename ArgT0 = const std::string&, typename... ArgT>
        void set_unit_address(ArgT0&& arg0, ArgT... args);
        std::string* mutable_unit_address();
        PROTOBUF_NODISCARD std::string* release_unit_address();
        void set_allocated_unit_address(std::string* unit_address);
    };
    
    // 更新的 PeopleInfo 类
    class PeopleInfo final : public ::PROTOBUF_NAMESPACE_ID::Message 
    {
    public:
        // .google.protobuf.Any data = 4;
        bool has_data() const;
        void clear_data();
        const ::PROTOBUF_NAMESPACE_ID::Any& data() const;
        PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::Any* release_data();
        ::PROTOBUF_NAMESPACE_ID::Any* mutable_data();
        void set_allocated_data(::PROTOBUF_NAMESPACE_ID::Any* data);
    };
    
  • 上述代码中,对于Any字段
    • 设置和获取
      • 获取⽅法的⽅法名称与字段命名完全相同
      • 设置⽅法可以使⽤mutable_⽅法,返回值为Any类型的指针,这类⽅法会为用户开辟好空间,可以直接对这块空间的内容进⾏修改
    • 可以在Any字段中存储任意消息类型,这就要涉及到任意消息类型和Any类型的互转
      • PackFrom():将任意消息类型转为Any类型
      • UnpackTo:将Any类型转回之前设置的任意消息类型
      • Is:用来判断存放的消息类型是否为typename T
      • 这部分代码就在 Google写好的⽂件any.pb.h
        class PROTOBUF_EXPORT Any final : public ::PROTOBUF_NAMESPACE_ID::Message 
        {
        	bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message) 
        	{
        		...
        	}
        	
        	bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const 
        	{
        		...
        	}
        	
        	template<typename T> bool Is() const 
        	{
        		return _impl_._any_metadata_.Is<T>();
        	}
        };
        

2.oneof类型

1.说明

  • 如果消息中有很多可选字段, 并且将来同时只有⼀个字段会被设置
    • 那么就可以使⽤oneof加强这个⾏为,也能有节约内存的效果
  • 注意
    • 可选字段中的字段编号,不能与⾮可选字段的编号冲突
    • 不能在oneof中使⽤repeated字段
    • 将来在设置oneof字段中值时,如果将oneof中的字段设置多个,那么只会保留最后⼀次设置的成员,之前设置的oneof成员会⾃动清除

2.代码&使用

  • .proto文件
    syntax = "proto3";
    package contacts;

    import "google/protobuf/any.proto"; // 引⼊ any.proto ⽂件

    message Address
    {
    string home_address = 1;
    string unit_address = 2;
    }

    message PeopleInfo
    {
    string name = 1;
    int32 age = 2;

    message Phone
    {
    string number = 1;
    enum PhoneType
    {
    MP = 0;
    TEL = 1;
    }
    PhoneType type = 2;
    }
    repeated Phone phone = 3;

    google.protobuf.Any data = 4;

    // 其他联系⽅式:多选⼀
    oneof other_contact
    {
    string qq = 5;
    string weixin = 6;
    }
    }

    message Contacts
    {
    repeated PeopleInfo contacts = 1;
    }
  • 编译生成的CPP代码
    // 更新的 PeopleInfo 类
    class PeopleInfo final : public ::PROTOBUF_NAMESPACE_ID::Message 
    {
        enum OtherContactCase 
        {
            kQq = 5,
            kWeixin = 6,
            OTHER_CONTACT_NOT_SET = 0,
        };
    
        // string qq = 5;
        bool has_qq() const;
        void clear_qq();
        const std::string& qq() const;
        template <typename ArgT0 = const std::string&, typename... ArgT>
        void set_qq(ArgT0&& arg0, ArgT... args);
        std::string* mutable_qq();
        PROTOBUF_NODISCARD std::string* release_qq();
        void set_allocated_qq(std::string* qq);
    
        // string weixin = 6;
        bool has_weixin() const;
        void clear_weixin();
        const std::string& weixin() const;
        template <typename ArgT0 = const std::string&, typename... ArgT>
        void set_weixin(ArgT0&& arg0, ArgT... args);
        std::string* mutable_weixin();
        PROTOBUF_NODISCARD std::string* release_weixin();
        void set_allocated_weixin(std::string* weixin);
        void clear_other_contact();
        OtherContactCase other_contact_case() const;
    };
    
  • 上述的代码中,对于oneof字段
    • 会将oneof中的多个字段定义为一个枚举类型
    • 设置和获取
      • oneof内的字段进⾏常规的设置和获取即可
      • 但要注意只能设置⼀个,如果设置 多个,那么只会保留最后⼀次设置的成员
    • 清空oneof字段:clear_⽅法
    • 获取当前设置了哪个字段:_case⽅法

3.map类型

1.说明

  • 语法⽀持创建⼀个关联映射字段,也就是可以使⽤map类型去声明字段类型,格式
    map<key_type, value_type> map_field = N;
  • 注意
    • key_type是除了floatbytes类型以外的任意标量类型
    • value_type可以是任意类型
    • map字段不可以repeated修饰
    • map 中存⼊的元素是⽆序的

2.代码&使用

  • .proto文件
    syntax = "proto3";
    package contacts;

    import "google/protobuf/any.proto"; // 引⼊ any.proto ⽂件

    message Address
    {
    string home_address = 1;
    string unit_address = 2;
    }

    message PeopleInfo
    {
    string name = 1;
    int32 age = 2;

    message Phone
    {
    string number = 1;
    enum PhoneType
    {
    MP = 0;
    TEL = 1;
    }
    PhoneType type = 2;
    }

    repeated Phone phone = 3;

    google.protobuf.Any data = 4;

    // 其他联系⽅式:多选⼀
    oneof other_contact
    {
    string qq = 5;
    string weixin = 6;
    }

    map<string, string> remark = 7;
    }


    message Contacts
    {
    repeated PeopleInfo contacts = 1;
    }
  • 编译生成的CPP文件
    // 更新的 PeopleInfo 类
    class PeopleInfo final : public ::PROTOBUF_NAMESPACE_ID::Message 
    {
        // map<string, string> remark = 7;
        int remark_size() const;
        void clear_remark();
        const ::PROTOBUF_NAMESPACE_ID::Map< std::string, std::string >& remark() const;
        ::PROTOBUF_NAMESPACE_ID::Map< std::string, std::string >* mutable_remark();
    };
    
  • 上述的代码中,对于Map类型的字段
    • 清空map:clear_ ⽅法
    • 设置和获取
      • 获取⽅法的⽅法名称与字段命名完全相同
      • 设置⽅法mutable_⽅法,返回值为Map类型的指针,这类⽅法会为用户开辟好空间,可以直接对这块空间的0内容进⾏修改

举报

相关推荐

0 条评论