c++ - 使用复制构造函数且存在虚函数时出现错误 "recursive on all control paths"

标签 c++ templates visual-c++ multiple-inheritance virtual-functions

下面的错误让我很困惑。这是一小段更复杂的代码。对我来说似乎很奇怪,只有模板化构造函数和虚方法的存在才会导致错误,并且只有在复制初始化对象时才会发生错误。

有人有想法吗?谢谢。

    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/

相关文章:

c++ - 从不兼容类型 'char' 分配给 'void'

c++ - 引用函数按值返回和自动

c++ - 获取类中的字段数

c++ - -fno-char8_t 的 MSVC 等效项是什么?

c++ - 功能终止时发生访问冲突——为什么会发生这种情况?

c++ - 如何在 Windows 上以编程方式设置 GPU 核心和内存时钟?

c++ - 推荐一个生成打印预览和打印的方案

visual-studio-2008 - 如何在vs08中设置_win32_wce的预处理器定义

c++ - 成员函数指针的类型推导

C++:二叉搜索树适用于整数,但在我尝试传递字符串时崩溃