类树的一个分支如何使其所有零初始化成员都是垃圾?

Posted

技术标签:

【中文标题】类树的一个分支如何使其所有零初始化成员都是垃圾?【英文标题】:How can one branch of class tree have all its Zero initialized members be rubbish? 【发布时间】:2013-01-24 12:04:48 【问题描述】:

(仅当零初始化为静态范围成员时才不是垃圾。)它可以工作as expected on GCC!(((

所以对于像这样的代码:

#include <iostream>
#include <boost/shared_ptr.hpp>

namespace SP

    // enums
    enum EnumMessage 
        EnumMessage_EventBase = 0,
        EnumMessage_EventServiceBase = 1,
        EnumMessage_OperationBase = 2
    ;

    class Message;

    // define proxy class
    class Message  
    public:
        EnumMessage _MessageCode;
    ;

    class Parent : public Message 
    public:
        int _ServiceId;
        int _CallbackId;
    ;

    class Child : public Parent 
    public:
        std::string _Debug;
    ;

    class AnotherChild : public Parent 
    public:
        int _UserId;
    ;


using namespace SP;

int main() 
    //OK
    static Child staticScopeChild = Child();
    boost::shared_ptr<Parent> ptrParent(new Parent());
    boost::shared_ptr<AnotherChild> ptrChild2(new AnotherChild());

    //Bad
    Child scopeChild = Child();
    boost::shared_ptr<Child> ptrChild(new Child());


    std::cout << "static " << staticScopeChild._MessageCode 
        << std::endl << "vs scope " << scopeChild._MessageCode 
        << std::endl << "vs pointer " << ptrChild->_MessageCode 
        << std::endl << "vs parent class pointer: " << ptrParent->_MessageCode 
        << std::endl << "vs another parent child: " << ptrChild2->_MessageCode <<std::endl;
    std::cin.get();
    return 0;

所有类通常都是 POD(intsenums)我得到下一个输出:

static 0
vs scope -858993460
vs pointer -842150451
vs parent class pointer: 0
vs another parent child: 0

虽然我希望所有人都是0

为什么会发生这样的事情?

【问题讨论】:

我对那个子分支中的所有类进行了如此糟糕的零初始化......虽然在所有其他分支中一切正常,这些分支似乎与那个破碎的分支没有什么不同。((() > 向我们展示Child构造函数。 听起来Child的构造函数没有初始化$MessageCode;因此静态对象将被零初始化,而其他对象将具有不确定的值。但是没有看到构造函数,我只能猜测。 (顺便说一句,在标识符中使用$ 或除_ 之外的任何非字母数字字符是不可移植的。) 看看答案……这就是我所说的“VC++ 怪异”。如果您让 VC2010 处理您忘记指定的任何内容,请准备好大吃一惊。我不知道VC2012。我已经在这条船上工作了 8 年。 【参考方案1】:

这似乎是一个编译器错误:根据this report,基类的成员在派生类的值初始化期间未进行零初始化。

据我所知,您的代码没有任何问题,并且所有类成员都应在符合 C++03 或 C++11 的编译器上进行零初始化。

我猜你的选择是:

通过避免继承使类更像POD;或 将默认构造函数添加到任何基类以显式零初始化所有成员;或 使用损坏较少的编译器。

【讨论】:

避免继承不会使类成为 POD,因为 Child 包含一个不是 POD 的 std::string 类型的成员。不过我喜欢最后一个建议:) -- +1 因为答案是正确的,因为在调用默认构造函数之前成员应该被零初始化。 @DavidRodríguez-dribeas:确实如此。但是,如果没有继承,它可能足够类似于 POD 以使值初始化工作。 请提交错误报告,让我们看看官方答案。 @myWallJSON:有人已经有了 - 请参阅我在答案的第一句话中包含的link。

以上是关于类树的一个分支如何使其所有零初始化成员都是垃圾?的主要内容,如果未能解决你的问题,请参考以下文章

层次聚类

机器学习--聚类系列--层次聚类

对比Dijakstra和优先队列式分支限界

R语言层次聚类模型示例

层次聚类算法的原理及实现Hierarchical Clustering

详细讲解 —— 结构体(C语言初阶)