在 C++ 中禁用复制构造函数并使用对象

disabling copy constructor in c++ and use of an Object

本文关键字:对象 构造函数 复制 C++      更新时间:2023-10-16

使用以下代码:

#include <iostream>

class A
{
    public:
        A(int truc) : truc(truc) {}
        A(const A & other) = delete;
    private:
        int truc;
};
class B
{
    public:
        B(int machin, A a) : machin(machin), a(a) {}
    private:
        int machin;
        A a;
};
int main()
{
  A a(10);      
  B b(2,a);
  return 0;
}

我收到一个编译错误"错误:使用已删除的函数'A::A(const A&)"

如果我仍然希望类 A 无法被复制,我该如何绕过这个问题?

B::B(int machin, A a)中的值获取A是主要问题,请B::B(int machin, A& a)B::B(int machin, const A& a)。这同样适用于构造函数主体中字段的赋值。因此,类B中的字段声明应分别A& a;const A& a;

但是,您可能还希望删除赋值运算符:A& operator=( const A& ) = delete;

看看提升不可复制。

它的实现还取决于 C++11 是否可用:http://www.boost.org/doc/libs/1_60_0/boost/core/noncopyable.hpp

考虑到复制的替代方法是移动,您需要:

   B(int machin, A&& a) : machin(machin), a(a) {}

这正确地不允许A a(10); B b(2,a);这是a的副本。你现在需要那里std::move(a)

B 的构造函数按值获取类型为 A 的对象 ->创建新对象(副本)

B(...,A a) ...
       ^^^^ pass by value

通过引用传递不会创建新对象(副本)。

B(...,A &a)...
       ^^^^^ pass by reference -> no copy

此外,这意味着您不能将其作为对象A a存储在B中,因为这会再次创建新对象(副本),您必须将其存储为引用。

这可能会导致一些问题:

B* createNewObject()
{
   A a(...); //local object is created
   B* ptr = new B(...,a); // reference in B now refers to local object
}// However, here is local object destroyed, so reference in B is now invalid (dangling reference)
int main()
{
   B *pb = createNewObject();
   //Any operation on B working with that invalid reference causes UNDEFINED BEHAVIOUR
}

此外,请记住,a的任何更改也会更改您传递的对象(因为该引用引用您传递的同一对象)。