如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作?

2022-01-18 00:00:00 initialization c++

我知道 memset 对于 class 初始化是不受欢迎的.例如,如下所示:

I know that memset is frowned upon for class initialization. For example, something like the following:

class X { public: 
X() { memset( this, 0, sizeof(*this) ) ; }
...
} ;

如果混合有 virtual 函数,将破坏 vtbl.

will clobber the vtbl if there's a virtual function in the mix.

我正在开发一个(庞大的)遗留代码库,它是 C 风格但用 C++ 编译的,所以所有有问题的成员通常都是 POD,不需要传统的 C++ 构造函数.C++ 的使用逐渐普及(就像虚函数一样),这让那些没有意识到 memset 具有这些额外的 C++ 优势的开发人员陷入了困境.

I'm working on a (humongous) legacy codebase that is C-ish but compiled in C++, so all the members in question are typically POD and require no traditional C++ constructors. C++ usage gradually creeps in (like virtual functions), and this bites the developers that don't realize that memset has these additional C++ teeth.

我想知道是否有一种 C++ 安全的方法来进行初始的全覆盖零初始化,然后可以在不适合零初始化的情况下进行特定的成员初始化?

I'm wondering if there is a C++ safe way to do an initial catch-all zero initialization, that could be followed by specific by-member initialization where zero initialization isn't appropriate?

我发现类似的问题memset for initialization in C++和使用 memset 对派生结构进行归零.这两个都有不要使用 memset()"的答案,但没有好的选择(尤其是对于可能包含许多成员的大型结构).

I find the similar questions memset for initialization in C++, and zeroing derived struct using memset. Both of these have "don't use memset()" answers, but no good alternatives (esp. for large structures potentially containing many many members).

推荐答案

对于每个找到 memset 调用的类,添加一个忽略指针的 memset 成员函数和大小参数,并对所有数据成员进行赋值.

For each class where you find a memset call, add a memset member function which ignores the pointer and size arguments and does assignments to all the data members.

实际上,它不应该忽略指针,它应该将它与 this 进行比较.在匹配时,为对象做正确的事情,在不匹配时,重新路由到全局函数.

edit: Actually, it shouldn't ignore the pointer, it should compare it to this. On a match, do the right thing for the object, on a mismatch, reroute to the global function.

相关文章