在C ++中复制构造函数

这个问题在这里已经有了答案:

  • 什么是三项规则? 8个答案

  • (1)成员变量的类型并不重要,它们的语义是。 规则很简单:

    如果你没有提供拷贝构造函数,编译器会尝试为你生成一个拷贝构造函数。 这个默认生成的将对所有成员变量执行默认的复制操作。 对于类类型,这意味着调用复制构造函数。 对于原始类型,这意味着按位复制。

    如果默认生成的构造函数执行你所需要的,不要声明你自己的。 如果它不能满足你的需求,请自己申报。 可以使用非原始成员变量和完全确定的默认复制语义创建一个类:

    struct PersonId
    {
      std::string surname;
      std::vector<std::string> givenNames;
    };
    

    同样,可以创建一个具有原始类型成员变量的类,其中默认的复制语义不会正常:

    class UniqueNamed
    {
      int id;
      UniqueNamed() : id(0) {}
    
    public:
      UniqueNamed(const UniqueNamed &src) : id(src.id + 1) {}
    
      int getId() const { return id; }
    
      static UniqueNamed initial;
    };
    

    所以它取决于类的语义,而不取决于其数据成员的类型。

    这涉及C ++中复制,移动和授权语义以及它们的实现的一般概念。 你可能想读一些关于零,三,五规则的东西。


    (1)当然,如果任何成员变量是不可复制的类型,并且你希望你的类是可复制的,你必须自己提供拷贝构造函数,因为缺省声明的类将被定义为删除。


    如果需要通过复制每个数据成员的值来复制对象,则不需要编写一个; 隐式生成的将完全做到这一点。

    如果在复制对象时需要发生其他情况,或者如果某些内容阻止了隐式对象的生成(例如, const数据成员),并且您仍然希望能够复制该对象,则需要编写一。


    如果你没有编写一个拷贝构造函数,就会创建一个缺省的拷贝构造函数,它会逐个拷贝你的类的每个字段,并调用它们的拷贝构造函数(如果有的话)。

    例如 :

    class Test {
    public:
      int toto;
      char titi;
    };
    
    int main() {
        Test a;
    
        a.toto = 42;
        a.titi = 'a';
        Test b(a); // b will be initialized with same fields than a.
    
        return (0);
    }
    

    注意这个方法:只用于简单的类,正如你所说的那样,只使用标准的C ++数据类型的字段。

    这里最常见的错误是当你的类有一个指针字段时:指针被复制,但不被重新分配,所以你将有两个类的实例,指针指向同一个事物,如果其中一个修改或删除它,另一个人会感受到后果。

    class Test {
    public:
      std::string* field;
    
      Test() {
          field = new std::string("toto");
      }
      ~Test() {
          delete (field);
      }
    };
    
    int main () {
        Test a; // a.field is allocated.
    
        Test b(a); // b have the same pointer than a, as if you did b.field = a.field.
        // Here a and b destructors are called. They will delete the same pointers twice.
        // It will result as a segmentation fault.
        return (0);
    }
    

    注意 :对于=运算符也是如此,如果不超载的话。

    链接地址: http://www.djcxy.com/p/73183.html

    上一篇: Copy Constructor in C++

    下一篇: double free or corruption (runs ok if reorder lines)