我正在阅读“经典C ++中的Advance Metaprogramming”一书!在第16页上,作者提供了一个例子:
struct base
{
base() {}
template <typename T>
base(T x) {}
};
struct derived : base
{
derived() {}
derived(const derived& that)
: base(that) {}
};
void main()
{
derived d1;
derived d2 = d1; //stack overflow!! why?!
}
作者说: “赋值d2 = d1导致堆栈溢出。隐式复制构造函数必须调用基类的复制构造函数,所以通过它上面的12.8(C ++标准)可以 永远不要调用通用构造函数。如果编译器为派生生成了一个拷贝构造函数,它就会调用基本拷贝构造函数(它是隐式的)。不幸的是,给出了一个派生的拷贝构造函数,它包含一个显式函数调用,即base(that)。因此,遵循通常的重载决策规则,它匹配通用构造函数与T = derived。由于此函数采用x by value,因此需要执行该操作的副本,因此调用是递归的。“
我真的没有得到它!有人可以解释一下这个!
非常感谢!:)答案 0 :(得分:6)
主要问题在于:
base(T x) {}
base的构造函数将x(表示d1)作为值,这会导致临时复制x。复制x将导致再次调用派生的原始复制构造函数,即这一个:
derived(const derived& that)
: base(that) {}
这个构造函数本身会再次调用第一个(base(T x)),因此会出现由递归构造函数调用引起的堆栈溢出。