Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么要创建两次数据对象?_C++ - Fatal编程技术网

C++ 为什么要创建两次数据对象?

C++ 为什么要创建两次数据对象?,c++,C++,我最近遇到了以下问题,不幸的是,我无法理解为什么在下面的代码中会创建两次数据对象 我认为一旦在Base(_data=I)中执行了_data=I,它将一直可用,直到派生被销毁,但正如输出所示,情况并非如此 如果能给我一个有助于我理解这个概念的逻辑解释,我将不胜感激 struct Data { Data(int i_ = 0 ) : _i(i_) { cout << "Inside Data::ctor" << endl; } ~Data() { cout &

我最近遇到了以下问题,不幸的是,我无法理解为什么在下面的代码中会创建两次数据对象

我认为一旦在Base(_data=I)中执行了_data=I,它将一直可用,直到派生被销毁,但正如输出所示,情况并非如此

如果能给我一个有助于我理解这个概念的逻辑解释,我将不胜感激

struct Data
{
    Data(int i_ = 0 ) : _i(i_) { cout << "Inside Data::ctor" << endl; }
    ~Data() { cout << "Inside Data::dtor" << endl ; }

    int _i;
};

struct Info
{
    Info(Data* d_)
    {
            cout << "Inside Info::ctor" << endl;
            cout << d_->_i << endl ;
            d_->_i = 1;
    }

};

struct Base
{
    Base(const Data& data_)
    {
            cout << "Inside Base::ctor" << endl;
            cout << data_._i << endl;
    }
};

struct Derived : public Base
{
    Derived(int i_) : _info(&_data), Base(_data = i_)
    {
            cout << "Inside Derived::ctor" << endl;
            cout << _data._i << endl ;
    }

    Data _data;
    Info _info;
};

int main()
{
    Derived d(100);

    return 0;
}

也许在初始值设定项列表中使用成员变量不是一个好主意。我假设先调用
Base
的构造函数,它会得到某种临时的
数据,因为
\u Data
尚未构造。然后在从
Base::Base
(并销毁临时
数据
)返回后,
\u数据
最终使用默认构造函数构造(因为它没有列在初始值设定项列表中,至少没有使用构造函数语法)。整个问题是
Base(_data=i_)
,因为
\u data
尚未构建。我假设首先调用基类的构造函数get,然后调用成员变量get。请记住,对象不是按照它们在初始值设定项列表中出现的顺序构造的,而是按照它们声明的顺序构造的。

请注意:

Derived(int i_) : _info(&_data), Base(_data = i_)
编译器可能生成了一个您忽略的警告。
不要忽略警告-它们是代码中的逻辑错误

构造函数将始终按以下顺序调用构造函数:

  • 首先调用Base()作为基构造函数:
  • data()首先声明它
  • info()这将始终在最后调用
本部分:

Base(_data = i_)
info(&_data)
实际上是调用对未初始化成员的赋值,因为i_uu是一个整数,它在赋值之前首先调用data()的默认构造函数(从而生成第一个print语句)

本部分:

Base(_data = i_)
info(&_data)
这里传递的是一个技术上未初始化的对象的地址(尽管它是非法初始化的(如上所述))。虽然传递未初始化对象的地址可能并不违法,但这是一个坏主意,因为您传递它的对象也不知道它没有正确初始化,因此任何用法都是无效的

您的输出描述如下:

Inside Data::ctor         // _data = i_; use i to create temporary object to assign to data.    
Inside Base::ctor         // Base Class constructor
100
Inside Data::dtor         // The temporay object (see above) is destroyed
Inside Data::ctor         // The member _data is initialized
Inside Info::ctor         // The member _info is initialized

谢谢我不确定我是否理解了临时对象的创建,但它更清楚一点。顺便说一句,g++没有生成任何警告或错误。编译是干净的。@deltarogue:最小标志:
g++-Wall