Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.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++;对于包含复合类的派生类,如何使用运算符new进行直接初始化?_C++ - Fatal编程技术网

C++ C++;对于包含复合类的派生类,如何使用运算符new进行直接初始化?

C++ C++;对于包含复合类的派生类,如何使用运算符new进行直接初始化?,c++,C++,我有这个密码。我知道main的第一行调用默认构造函数。我不明白第二行是怎么工作的。输出应为: X::X(&X) X::X(&X) X::X() Y::Y(X) X::X(&X) Z::Z(X) ~X::X() 它调用显式构造函数Z(X xx),但之后它执行什么步骤? 我假设两个第一cout与类Y中的复合类有关。 第三个cout只是X的一个默认c'tor,但为什么它创建它并在最后销毁它呢 另一个问题是关于main的第四行。输出应该是 X::X() X::X() Y::Y(

我有这个密码。我知道main的第一行调用默认构造函数。我不明白第二行是怎么工作的。输出应为:

X::X(&X) X::X(&X) X::X() Y::Y(X) X::X(&X) Z::Z(X) ~X::X()
它调用显式构造函数Z(X xx),但之后它执行什么步骤? 我假设两个第一cout与类Y中的复合类有关。 第三个cout只是X的一个默认c'tor,但为什么它创建它并在最后销毁它呢

另一个问题是关于main的第四行。输出应该是

X::X() X::X() Y::Y(Y&) Z::Z(&Z)
这里我不明白为什么前两个不是复制构造函数

#include <iostream>
using namespace std;

class X {
public:
    X() { cout << "X::X()" << endl; }
    X(const X& x) :t(x.t) { cout << "X::X(X&)" << endl; }
    X& operator=(const X& x) { cout << "X::op=" << endl;return *this; }
    ~X() { cout << "X::~X()" << endl; }
private:
    int t;
};

template<class T>
class Y {
public:
    Y() { cout << "Y::Y()" << endl; }
    Y(const X* pxx):x(*pxx){ cout << "Y::Y(X)" << endl; }
    Y(const T& tt):t(tt){ cout << "Y::Y(T)" << endl; }
    Y(const Y& y){ cout << "Y::Y(Y&)" << endl; }
    Y& operator=(const Y& y) { x = y.x;cout << "Y::op=" << endl;return       *this; }
    ~Y(){ cout << "Y::~Y()" << endl; }
protected:
    X x;
    T t;

};

class Z :public Y<X> {
public:
    Z() { cout << "Z::Z()" << endl; }
    Z(X xx):Y<X>(&xx), k(xx){ cout << "Z::Z(X)" << endl; }
    Z& operator=(const Z& z) { k = z.k; cout << "Z::op=" << endl; return  *this;     }
    ~Z(){ cout << "Z::~Z()" << endl; }
private:
    X k;
};

int main(){
    X* px = new X;
    Z* pzz = new Z(*px);
    Z* pz = new Z;
    Z z = *pz;

    return 0;

}
#包括
使用名称空间std;
X类{
公众:

X(){cout逐步获取输出:

X::X(&X) 
Z
的转换构造函数按值获取
xx
,因此调用
X
的复制构造函数

X::X(&X) 
来自
const X*
Y
转换构造函数再次为其成员
X
复制
X

X::X()
由于您没有在初始化列表中初始化
Y::t
,因此现在将调用默认构造函数对其进行初始化

Y::Y(X)
现在我们进入
Y
构造函数的主体

X::X(&X) 
这是为
Z::k

Z::Z(X) 
现在我们到达
Z
构造函数体

~X::X()
X::X(&X)
Z
构造函数创建的
X
xx
)副本现在已销毁

第2部分:行应该是
X::X()X::X()Y::Y(Y&)X::X(X&)

Y::x的默认构造函数

X::X() 
Y::t的默认构造函数

Y::Y(Y&) 
Y
复制构造函数主体

~X::X()
X::X(&X)
Z::x
的复制构造函数


惊讶?问题是表达式
Z=*pz;
实际上调用了
Z
的复制构造函数,也就是说,这与说
Z(*pz)没有什么不同
。您尚未为
Z
定义复制构造函数,但在这种情况下,编译器可以为您创建一个复制构造函数,只需复制所有基和成员。

编译器可以根据需要自由创建任意多个或任意少个副本。因此,如果打开/关闭优化,或者使用不同的编译器,您可能会获得不同的输出,等等。@保罗·麦肯齐:这并不完全准确。在某些情况下,编译器可以删除副本,但现在不是开放季节,特别是当复制/移动构造函数有副作用时。如果复制构造函数有副作用,那是程序员的问题/错误,而不是编译器的问题。编译器仍然可以自由删除ide复制。关于析构函数~X::X(),我还有一个问题。你说:“为Z构造函数创建的X的副本现在被销毁了”。它是X::k吗?如果是,为什么它会销毁它?@Vlad这是
xx
的析构函数。