下面的错误让我很困惑。这是一小段更复杂的代码。对我来说似乎很奇怪,只有模板化构造函数和虚方法的存在才会导致错误,并且只有在复制初始化对象时才会发生错误。
有人有想法吗?谢谢。
class A
{
long *p;
public:
A():p(0)
{
}
template<class T>
A(T val):p(val)// 1
{
}
operator long*()
{
return p;
}
};
class B
{
virtual void f()// 2
{
}
};
class C : public A, public B
{
};
void main()
{
C c;
main()
的下一行是
A a=c;
如果标记为 //1
和 //2
的行都存在,则会触发以下错误:
warning C4717: 'C::C' : recursive on all control paths, function will cause runtime stack overflow
但是在main()
中使用下面的语句时,没有报错:
A a;
a=c;
}
最佳答案
您拥有的是 copy elision 的令人讨厌的汇合和一个制作参数拷贝的构造函数。
首先要澄清一个误会:A a = c;
不等于A a; a = c;
.第一个调用复制构造函数,第二个调用赋值运算符。使用 this code sample 亲自查看.
构造函数A::A<T>(T)
可以复制 T
每当它被调用时。不幸的是,如果您使用 A
调用它参数(或在您的示例中 C
,它是一个 A
),该参数将尝试复制自身,调用 A::A<T>(T)
再次,它一次又一次地复制自己……直到堆栈溢出。
当您没有 virtual void f()
时为什么不会发生这种情况?在 B
?这是复制省略的副作用,它是一个依赖于实现的特性。拥有虚拟方法可能足以让 visual studio 决定不删除拷贝,但无论如何你不应该依赖它。这就是为什么你是strongly advised not to have observable side-effects for copy ctors .
以防万一您正在寻找解决方案,您可以通过更改 A::A<T>(T)
来删除拷贝引用,例如 A::A<T>(T&)
.更好的是,拿 const T&
因为这有助于确保 ctor 中没有副作用(因为您无法修改 T
)。
关于c++ - 使用复制构造函数且存在虚函数时出现错误 "recursive on all control paths",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15800440/