成员变量是引用,需要通过初始化列表来初始化

需求 类中包含的成员变量是引用,如何对这种引用成员变量进行初始化? 解决 这种引用成员变量初始化只能使用初始化列表。 class CommandProcess { public: CommandProcess(uint64_t& send_count); private: uint64_t& msg_send_count_; }; CommandProcess::CommandProcess(uint64_t& send_count) : msg_send_count_(send_count) { } 参考 C/C++ - 类中成员变量是引用

2023-05-10 · 1 min · 24 words · RamLife

weak_ptr 给构造函数引用参数必须是 const, 否则 error: cannot bind non-const lvalue reference of type to an rvalue of type

需求 A类掌握资源,使用 shared_ptr 来指向资源。其他 B,C,D 类使用资源,在构造函数中使用 weak_ptr 作为引用参数来接收资源指针。但是编译是会报错,报错信息: error: cannot bind non-const lvalue reference of type ‘std::weak_ptr<>&’ to an rvalue of type ‘std::weak_ptr<>’ 解决 解决办法很简单,在构造函数的参数 weak_ptr 前面加上 const. std::unique_ptr<CommandProcess> process_; std::shared_ptr<MessageQueue> send_; process_ = make_unique<CommandProcess>(send_); CommandProcess::CommandProcess(const weak_ptr<MessageQueue>& send) : send_(send) { } 参考 c++ 智能指针 传参 GotW #91 Solution: Smart Pointer Parameters C/C++面试:weak_ptr的使用场景 关于c ++:我应该通过引用传递shared_ptr吗? C++ shared_ptr 作为参数和返回值的比较 C++11:再谈shared_ptr,以及shared_ptr参数传递以及构造细节 C++非const引用问题:error: cannot bind non-const lvalue reference of type 【报错】关于{Error} cannot bind non-const lvalue reference of type ‘std::String&‘ to an rvalue……的一个解决方案...

2023-05-10 · 1 min · 81 words · RamLife

c++ error: is an inaccessible base of

需求 今天编译报错 error: is an inaccessible base of 解决 这个问题解决也非常简单,主要是默认的继承实际上是 private, 所以不能直接访问父类的成员,只要在继承时,用 public 进行标识即可。 class A { public: virtual int add(int a, int b); }; class B : public A { int add(int a, int b) { return a + b; } }; 参考 ‘A’ is an inaccessible base of ‘B’解决方案 C++ is an inaccessible base of 问题的解决方法

2023-05-10 · 1 min · 58 words · RamLife

c++ 子类构造初始化和父类构造初始化

需求 子类构造时会调用父类构造函数,具体如何匹配? 解决 父类 子类 匹配 null null 编译器默认生成 父类和子类的构造函数 null 无参 或 带参 调用编译器生成的父类构造函数 无参 没有显式调用父类构造函数 隐式调用父类无参构造函数 带参 必须显式调用父类构造函数 显式调用,否则编译会报错 带参且都有默认值 不用显式调用父类构造函数 可以隐式调用父类有默认值的带参构造函数 无参或带参 只需要实现父类构造函数中的任何一个即可 没有显式调用的情况下,默认调用父类无参构造函数 参考 c++ 子类构造函数初始化及父类构造初始化 C++子类构造函数初始化及父类构造初始化

2023-05-10 · 1 min · 31 words · RamLife

c++ struct 使用初始化列表无效

需求 今天使用统一初始化, {} 初始化 struct 之后,发现数据还是 0,没有初始化进去。 解决 经过网上查找之后,找到问题所在,列表初始化只能用于 aggregate, 而 class, struct, union 是否属于 aggregate, 需要满足以下几个条件: 无自定义构造函数 无私有或受到保护的非静态数据成员 无基类 无虚函数 类的定义中,不能有被 {} 和 = 直接初始化的非静态数据成员 // 自定义构造函数 struct Test { int x; int y; Test(int, int) {} }; // 保护非静态数据成员 struct Test { int x; int y; protected: int z; }; // 基类 struct base{}; struct Test : base { int x; int y; }; // 虚函数 struct Test { int x; int y; virtual void func(int, int) {} }; // 直接初始化 struct Test { int x; int y = 5; }; 所以只要注意以上几点即可,但是如果一定要这种情况下还要能使用列表进行初始化,也是可以的,需要如下定义:...

2023-04-27 · 1 min · 116 words · RamLife

子类调用父类被重写的虚函数

需求 今天需要在子类的虚函数中,调用父类被重写的同名方法,来完成部分工作。 解决 this->Command::ToString(cmd) 类似上面这样,可以通过 this 指针直接拿到父类的方法 Command::ToString . 编译器可以自动找到并调用父类的方法。 参考 C++——子类调用父类方法 c++父类虚函数被子类虚函数覆盖后,如何直接调用父类的虚函数? C++ | 子类对象调用父类函数

2023-04-19 · 1 min · 16 words · RamLife

构造函数可以调用成员函数吗?

需求 构造函数中可以使用成员函数吗? 如何可以的话,就可以多个构造函数,通过调用同一个成员函数,来提高代码复用。 解决 构造函数可以直接调用成员函数,因为成员函数在编译期就已经定下来了,在运行期执行构造函数,调用成员函数没有问题。 参考 构造函数中调用成员函数??

2023-04-12 · 1 min · 7 words · RamLife

'undefined reference to vtable for'

需求 今天编译的时候,报错 undefined reference to vtable for. 解决 这个报错就是说的虚函数没有找到对应的定义。经过多次仔细的检查后,发现是某个暂时没有用到的纯虚函数,在子类中没有相应的函数体。给这个函数加上 {} 就可以暂时解决了。 参考 C++ 基类继承 出现undefined reference to vtable for Cxxx错误 QT cmake编译时总显示undefined reference to `vtable for xxx‘ C++ 从命令行编译一个Qt单个文件:对vtable的未定义引用

2023-04-11 · 1 min · 29 words · RamLife

c++ 用于解析 xml 文件的第三方库

需求 在 C++ 环境下,能够解析 xml 文件的第三方库? 解决 经过尝试之后,比较合适的是 tinyxml 这个第三方库,可以创建,插入,删除,修改,解析 xml 文件。 参考 C/C++ 使用 tinyxml库 操作XML格式文件(创建、插入、删除、修改、解析) C++解析XML TinyXML Files

2023-04-10 · 1 min · 20 words · RamLife

c++ utf8 和 utf16 转换

需求 有一个 xml 文件,是 utf16-be 格式的,直接使用 firefox 打开不对,所以考虑先转码为 utf8 然后再打开。 解决 int Utf16leToUtf8(uint8_t* dest, int dest_size, int* dest_len, uint16_t* src, int src_len) { uint8_t* dest_start = dest; uint8_t* dest_end = dest + dest_size; //uint16_t* src_end = (uint16_t*)((uint8_t*)src + src_len); uint16_t* src_end = src + src_len; while (src < src_end) { if (*src < UTF16_2 && dest + 1 < dest_end) { //0000 - 007F : 0xxxxxxx *dest++ = (uint8_t)*src; } else if(*src >= UTF16_2 && *src < UTF16_3 && dest + 2 < dest_end) { //0080 - 07FF : 110xxxxx 10xxxxxx *dest++ = ((*src >> 6) & 0x1F) | 0xC0; *dest++ = (*src & 0x3F) | 0x80; } else if(*src >= UTF16_3 && *src < UTF16_4 && dest + 3 < dest_end) { //0800 - FFFF : 1110xxxx 10xxxxxx 10xxxxxx *dest++ = ((*src >> 12) & 0x0F) | 0xE0; *dest++ = ((*src >> 6) & 0x3F) | 0x80; *dest++ = (*src & 0x3F) | 0x80; } else if(*src >= UTF16_4 && *src < UTF16_4_SECOND && dest + 4 < dest_end) { // 代理项对部分(4字节表示) //0001 0000 - 001F FFFF : 1111 0xxx 10xxxxxx 10xxxxxx 10xxxxxx // 从代理项对到UNICODE代码点转换 // 1、从高代理项减去0xD800,获取有效10bit // 2、从低代理项减去0xDC00,获取有效10bit // 3、加上0x10000,获取UNICODE代码点值 uint16_t high_sur = *src++; uint16_t low_sur = *src; uint32_t code_point = high_sur - UTF16_4; code_point <<= 10; code_point |= low_sur - UTF16_4_SECOND; code_point += UTF16_4_PLUS; *dest++ = (code_point >> 18) | 0xF0; *dest++ = ((code_point >> 12) & 0x3F) | 0x80; *dest++ = ((code_point >> 06) & 0x3F) | 0x80; *dest++ = (code_point & 0x3F) | 0x80; } else { break; } src++; } *dest = 0; *dest_len = dest - dest_start; if (src < src_end) { return -1; } return 0; } int Utf16beToUtf8(uint8_t* dest, int dest_size, int* dest_len, uint16_t* src, int src_len) { uint16_t le[src_len]; union { uint16_t s; uint8_t buf[sizeof(uint16_t)]; } data; for (int i = 0; i < src_len; i++) { /* uint8_t * d = (uint8_t *)(src + i); uint8_t tmp = *d; *d = *(d + 1); *(d + 1) = tmp; */ data....

2023-04-10 · 2 min · 367 words · RamLife