概述
文章目录
- 原文
- C++结构体初始化不推荐使用memset函数,推荐使用花括号或者显式调用默认构造函数初始化
- 使用花括号ky_ai_algorithm_info algo_info{};初始化和显示调用默认构造函数初始化ky_ai_algorithm_info algo_info = ky_ai_algorithm_info();区别
原文
我这有个结构体:
VENC_CHN_ATTR_S venc_chn_attr;
/* the attribute of the venc chnl*/
typedef struct rkVENC_CHN_ATTR_S { //视频编码通道属性结构体
VENC_ATTR_S stVencAttr; // the attribute of video encoder
VENC_RC_ATTR_S stRcAttr; // the attribute of rate ctrl
VENC_GOP_ATTR_S stGopAttr; // the attribute of gop
} VENC_CHN_ATTR_S;
/* the attribute of the Venc*/
typedef struct rkVENC_ATTR_S { //编码参数结构体
CODEC_TYPE_E enType; // RW; the type of encodec
IMAGE_TYPE_E imageType; // the type of input image
RK_U32 u32VirWidth; // stride width, same to buffer_width, must greater than
// width, often set vir_width=(width+15)&(~15) //幅长
RK_U32 u32VirHeight; // stride height, same to buffer_height, must greater
// than height, often set vir_height=(height+15)&(~15)
RK_U32 u32Profile; // RW;
// H.264: 66: baseline; 77:MP; 100:HP; //画质
// H.265: default:Main;
// Jpege/MJpege: default:Baseline
RK_BOOL bByFrame; // RW; Range:[0,1];
// get stream mode is slice mode or frame mode
RK_U32 u32PicWidth; // RW; width of a picture to be encoded, in pixel
RK_U32 u32PicHeight; // RW; height of a picture to be encoded, in pixel
VENC_ROTATION_E enRotation;
union {
VENC_ATTR_H264_S stAttrH264e; // attributes of H264e
VENC_ATTR_H265_S stAttrH265e; // attributes of H265e
VENC_ATTR_MJPEG_S stAttrMjpege; // attributes of Mjpeg
VENC_ATTR_JPEG_S stAttrJpege; // attributes of jpeg
};
} VENC_ATTR_S;
我在c++中用 = {0}初始化编译就报错:
VENC_CHN_ATTR_S venc_chn_attr = {0};
报错:
error: invalid conversion from ‘int’ to ‘CODEC_TYPE_E’ {aka ‘rk_CODEC_TYPE_E’} [-fpermissive]
VENC_CHN_ATTR_S venc_chn_attr = {0};
用memset函数就能正常编译通过:
memset(&venc_chn_attr, 0, sizeof(VENC_CHN_ATTR_S));
而在c中用 = {0}是可以正常编译过的,到了c++里就不行了。。
原因,c++中结构体不能用 = {0}来初始化,要用 = {}来初始化
参考文章:c++中结构体中套结构体不能用 = {0}来初始化吗? - 知乎
C++结构体初始化不推荐使用memset函数,推荐使用花括号或者显式调用默认构造函数初始化
不推荐使用 memset 来初始化一个结构体,特别是结构体内部包含 std::string 和 std::vector 这样的动态内存分配类型时,因为 memset 只会简单地把结构体中的所有字节都设置为0,这样可能会破坏动态分配的内存,导致程序崩溃或出现其他意想不到的问题。
相反,建议使用结构体的默认构造函数或手动初始化它的每个成员。如果你想要使用默认值初始化结构体,可以使用以下方式:
比如,我有以下结构体:
(某头文件中)
struct ky_ai_algorithm_info
{
std::string m_app_filename;
std::string m_algorithm_name;
std::string m_model_filename;
std::string m_cfg_filename;
std::string m_json_filename;
std::string m_desc;
std::string m_cmd;
bool m_is_running;
ky_ai_alg_json_cfg m_json_cfg;
};
(某cpp中)
ky_ai_algorithm_info algo_info{}; // 使用默认构造函数初始化
// 或者
ky_ai_algorithm_info algo_info = ky_ai_algorithm_info(); // 显式调用默认构造函数
如果需要手动初始化结构体中的某些成员变量,可以这样做:
ky_ai_algorithm_info algo_info;
algo_info.some_string_member = "some value";
algo_info.some_bool_member = true;
// 初始化 std::vector 成员,例如:
algo_info.some_vector_member = std::vector<int>{1, 2, 3};
注意:std::string 类型的成员变量,它们会被默认初始化为空字符串
使用花括号ky_ai_algorithm_info algo_info{};初始化和显示调用默认构造函数初始化ky_ai_algorithm_info algo_info = ky_ai_algorithm_info();区别
在大多数情况下,使用花括号初始化和显式调用默认构造函数初始化都可以达到相同的效果,即对结构体的所有成员变量进行默认初始化。
但是,这两种方式有些微妙的差别。使用花括号初始化语法时,如果定义的结构体没有默认构造函数,则会使用聚合初始化方式对结构体进行初始化,这意味着需要确保花括号中提供的值的数量和顺序与结构体中的成员变量相匹配,否则编译器会产生编译错误。在你的例子中,由于 ky_ai_algorithm_info 结构体只包含标准库的类型,因此它是一个聚合体,可以使用花括号初始化语法对其进行初始化。
使用显式调用默认构造函数初始化时,即 ky_ai_algorithm_info algo_info = ky_ai_algorithm_info();,会在堆栈上创建一个临时对象,并将其拷贝到 algo_info 变量中。如果你的结构体没有默认构造函数,则这种方式可以确保使用默认值初始化每个成员变量。这种方式的效率可能略低于使用花括号初始化,因为它需要创建一个临时对象,并在拷贝时执行一些不必要的操作。
总的来说,如果你的结构体是聚合体,则可以使用花括号初始化语法。如果你想确保使用默认构造函数初始化,则可以显示调用默认构造函数。
最后
以上就是高挑月饼为你收集整理的c++中结构体套结构体用 = {0}初始化编译报错解决办法(用memset或者={})(error: invalid conversion)的全部内容,希望文章能够帮你解决c++中结构体套结构体用 = {0}初始化编译报错解决办法(用memset或者={})(error: invalid conversion)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复