C++ C++;对于包含复合类的派生类,如何使用运算符new进行直接初始化?
我有这个密码。我知道main的第一行调用默认构造函数。我不明白第二行是怎么工作的。输出应为: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(
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
的析构函数。