元编程中的堆栈溢出

时间:2016-06-22 09:16:13

标签: c++11 inheritance stack-overflow copy-constructor template-meta-programming

我正在阅读“经典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,因此需要执行该操作的副本,因此调用是递归的。“

我真的没有得到它!有人可以解释一下这个!

非常感谢!:)

1 个答案:

答案 0 :(得分:6)

主要问题在于:

base(T x) {}

base的构造函数将x(表示d1)作为值,这会导致临时复制x。复制x将导致再次调用派生的原始复制构造函数,即这一个:

derived(const derived& that)
    : base(that) {}

这个构造函数本身会再次调用第一个(base(T x)),因此会出现由递归构造函数调用引起的堆栈溢出。