这个C ++结构初始化技巧是否安全? [英] Is this C++ structure initialization trick safe?

查看:77
本文介绍了这个C ++结构初始化技巧是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不必记住初始化一个简单的C结构,我可以从它派生并在构造函数中将其归零,如下所示:

Instead of having to remember to initialize a simple 'C' structure, I might derive from it and zero it in the constructor like this:

struct MY_STRUCT
{
    int n1;
    int n2;
};

class CMyStruct : public MY_STRUCT
{
public:
    CMyStruct()
    {
        memset(this, 0, sizeof(MY_STRUCT));
    }
};

这个技巧通常用于初始化Win32结构,有时可以设置无处不在的 cbSize member。

This trick is often used to initialize Win32 structures and can sometimes set the ubiquitous cbSize member.

现在,只要没有一个虚函数表用于memset调用destroy,这是一个安全的做法吗?

Now, as long as there isn't a virtual function table for the memset call to destroy, is this a safe practice?

推荐答案

PREAMBLE:



虽然我的答案还是,我发现litb's answer 相当优于我,因为:

PREAMBLE:

While my answer is still Ok, I find litb's answer quite superior to mine because:


  1. 它教我一个我不知道的骗子(litb的答案通常有这个效果,但这是我第一次写下来)

  2. 它回答的是正确的问题(也就是将初始结构的部分初始化为零)

litb的答案在我之前。

So please, consider litb's answer before mine. In fact, I suggest the question's author to consider litb's answer as the right one.

投放一个真正的对象(即std :: string)等会破坏,因为真正的对象将在memset之前被初始化,然后被零覆盖。

Putting a true object (i.e. std::string) etc. inside will break, because the true object will be initialized before the memset, and then, overwritten by zeroes.

初始化列表不工作的g ++(我很惊讶...)。在CMyStruct构造函数体中初始化它。它将是C ++友好的:

Using the initialization list doesn't work for g++ (I'm surprised...). Initialize it instead in the CMyStruct constructor body. It will be C++ friendly:

class CMyStruct : public MY_STRUCT
{
public:
    CMyStruct() { n1 = 0 ; n2 = 0 ; }
};



PS:我假设你对MY_STRUCT有没有 。使用控件,您将直接在MY_STRUCT中添加构造函数,并忘记关于继承。注意,你可以将非虚拟方法添加到类似C的结构,并且仍然具有结构的作用。

P.S.: I assumed you did have no control over MY_STRUCT, of course. With control, you would have added the constructor directly inside MY_STRUCT and forgotten about inheritance. Note that you can add non-virtual methods to a C-like struct, and still have it behave as a struct.

编辑:添加缺少括号,在Lou Franco的评论。谢谢!

Added missing parenthesis, after Lou Franco's comment. Thanks!

编辑2:我试过g ++上的代码,并且由于某种原因,使用初始化列表不工作。我使用正文构造函数更正了代码。

EDIT 2 : I tried the code on g++, and for some reason, using the initialization list does not work. I corrected the code using the body constructor. The solution is still valid, though.

请重新评估我的帖子,因为原始代码已更改(有关更多信息,请参阅changelog)。

Please reevaluate my post, as the original code was changed (see changelog for more info).

编辑3:阅读Rob的评论后,我想他有一个值得讨论的问题:同意,但这可能是一个巨大的Win32结构,可能会随着新的SDK改变,所以memset是未来的证明。

EDIT 3 : After reading Rob's comment, I guess he has a point worthy of discussion: "Agreed, but this could be an enormous Win32 structure which may change with a new SDK, so a memset is future proof."

我不同意:知道微软,它不会改变,因为他们需要完美的向后兼容性。他们将创建一个扩展的MY_STRUCT Ex 结构,它与MY_STRUCT具有相同的初始布局,在末尾使用了addnal成员,通过一个size成员变量,如用于RegisterWindow的结构体IIRC可以识别。

I disagree: Knowing Microsoft, it won't change because of their need for perfect backward compatibility. They will create instead an extended MY_STRUCTEx struct with the same initial layout as MY_STRUCT, with additionnal members at the end, and recognizable through a "size" member variable like the struct used for a RegisterWindow, IIRC.

因此,Rob的评论中剩下的唯一有效点是巨大的结构。在这种情况下,memset可能更方便,但是你必须让MY_STRUCT成为CMyStruct的可变成员,而不是继承它。

So the only valid point remaining from Rob's comment is the "enormous" struct. In this case, perhaps a memset is more convenient, but you will have to make MY_STRUCT a variable member of CMyStruct instead of inheriting from it.

我看到另一个黑客,我猜这会破坏,因为可能的结构对齐问题。

I see another hack, but I guess this would break because of possible struct alignment problem.

编辑4:请看看弗兰克·克鲁格的解决方案。我不能承诺它是可移植的(我猜是),但它仍然是有趣的从技术角度来看,因为它显示了一个案例,在C + +,这个指针地址从其基类移动到其继承类。

EDIT 4: Please take a look at Frank Krueger's solution. I can't promise it's portable (I guess it is), but it is still interesting from a technical viewpoint because it shows one case where, in C++, the "this" pointer "address" moves from its base class to its inherited class.

这篇关于这个C ++结构初始化技巧是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆