-2

IDE - 桌面版 Visual Studio Express 2013

C++11

问题 - 我有一个显然被复制的类(使用复制构造函数)。如果我这样声明复制构造函数:

MyClass(const MyClass&) = delete;

它抱怨对已删除函数的引用。我现在已经检查了我的整个代码两次,找不到类的实例将被复制到哪里。

有什么方法可以找到引用的来源?

我已经尝试定义复制构造函数,其中有一个断点,但它从未被命中。

更新

抱歉,它确实显示了引用的位置——在 STL 中的某个分配器中。我设法将其追踪到 std::vector::emplace_back() 调用 - 这必须导致副本。我将对此进行调查。

更新 2

我真是个笨蛋——我有一个 MyClass 的向量......

4

1 回答 1

3

也许您遇到了以下编译器错误

http://connect.microsoft.com/VisualStudio/feedback/details/889420/issue-with-delete

它说 IDE (IntelliSense) 会抱怨而编译器没有,这可以解释为什么您没有发布任何编译器错误消息以及为什么您实际上可以首先执行带有断点的已编译程序。

该错误本身很容易重现:

struct Example
{
  Example() {}
  Example(Example const &) = delete;
};

Example f()
{
  return Example();
}

int main()
{
  Example e = f();
}

使用 VC 2013 编译如下:

cl /nologo /EHsc /W4 /Za stackoverflow.cpp

没有错误,没有警告。

现在,如果您改为访问 http://www.compileonline.com/compile_cpp11_online.php并使用 GCC 4.7.2 编译相同的代码,则会出现预期的编译器错误:

main.cpp: In function ‘Example f()’:
main.cpp:9:18: error: use of deleted function ‘Example::Example(const Example&)’
   return Example();
                  ^
main.cpp:4:3: error: declared here
   Example(Example const &) = delete;
   ^
main.cpp: In function ‘int main()’:
main.cpp:14:17: error: use of deleted function ‘Example::Example(const Example&)’
   Example e = f();
                 ^
main.cpp:4:3: error: declared here
   Example(Example const &) = delete;
   ^

所以,你实际上有两个问题:

  1. 你的编译器有一个错误。这只能通过升级到更新版本(如果/当有可用版本)来解决。

  2. 您的代码为不允许复制的类调用复制构造函数。

第二个问题可以通过考虑 C++ 何时“间接”复制对象的规则来解决——或者即使实际复制被优化,也需要存在复制构造函数。再次检查代码寻找以下情况:

  • 按值传递。void f(MyClass obj);.
  • 按值返回。MyClass f();.
  • 投掷。throw MyClass();

第一个很容易修复:

void f(MyClass const &obj);

其他的需要更彻底的重新设计,因为返回或扔掉直接与防止复制的想法相矛盾。

于 2014-07-05T10:41:18.303 回答