简体   繁体   English

通过 C++ 中的构造函数复制 class

[英]Copying class by constructor in C++

I've got a class person that include name, ID and static constructor.我有一个 class 人,其中包括姓名、ID 和 static 构造函数。 I defined a copy constructor that copy only name to defining person.我定义了一个复制构造函数,它只将名称复制到定义人员。 Does anyone know why ID and counter aren't shown correctly after defining per_2?有谁知道为什么定义 per_2 后 ID 和 counter 没有正确显示? Do I have to define ID somehow that it's an exception and can't be copied?我是否必须以某种方式定义 ID 以使其异常且无法复制?

#include<iostream>
#include<string>

using namespace std;

class person {
  public:
    string name;
  int ID;
  static int counter;
  person();
  ~person();
  person(const person & );
};

int person::counter = 0;
person::person() {
  counter++;
  ID = counter;
}
person::~person() {

}
person::person(const person & obj) {
  this - > name = obj.name; //Here I define that only name is supposed to be copied
}

int main() {
  person per_1;
  per_1.name = "John";

  cout << per_1.ID << endl; // It gives 1 and it's fine.
  cout << person::counter << endl; // So does it.

  person per_2 = per_1; // Here I copy class and give per_1's variables to per_2.

  cout << per_2.ID << endl; // Here I expect 2, because constructor incremented counter and assigned it to per_2.ID while it gives -84534283.
  cout << person::counter << endl; // There is still 1, despite incrementing counter in constructor.

  system("Pause");
  return 0;
}

The default constructor is not called when you use the copy constuctor, but you can add a converting constructor that creates a person from a name and delegate to that constructor in other constructors.使用复制构造函数时不会调用默认构造函数,但您可以添加一个转换构造函数,该构造函数根据name创建person并委托给其他构造函数中的该构造函数。 I suggest delete ing the copy constructor and replacing it with a default move constructor though.我建议delete复制构造函数并将其替换为default的移动构造函数。 You probably don't want two person s with the same ID.您可能不希望两个person具有相同的 ID。

Example:例子:

#include <iostream>

class person {
public:
    int ID;
    std::string name;   
    static int counter;

    person();                             // default ctor
    explicit person(const std::string&);  // converting ctor
    person(const person &) = delete;      // copy ctor deleted to not get two persons
                                          // with the same ID
    person(person&&) = default;           // move ctor
};

int person::counter = 0;

person::person() :
    person("")                             // delegate
{}

person::person(const std::string& Name) :  // colon starts the member initializer list
    ID(++counter),
    name(Name)
{}

You can replace the separate default constructor and the converting constructor with one constructor by using a default value for name:您可以使用 name 的默认值将单独的默认构造函数和转换构造函数替换为一个构造函数:

person(const std::string& Name = {}) :
    ID(++counter),
    name(Name)
{}

The default constructor is not executed when the copy constructor is called.调用复制构造函数时不执行默认构造函数。 As a result, ID is not initialized in per_2 .因此, ID未在per_2中初始化。

You'll need to duplicate the code from the default constructor to assign the next available ID (or add a private member function to do that, and have both constructors call it).您需要从默认构造函数复制代码以分配下一个可用 ID(或添加私有成员 function 来执行此操作,并让两个构造函数都调用它)。

When you invoke the copy constructor, the default constructor is ignored.当您调用复制构造函数时,默认构造函数将被忽略。 Both an individual person's ID as well as person::counter are only altered by the default constructor, so this means that they will be ignored when the copy constructor is called.个人 ID 和person::counter都只由默认构造函数更改,因此这意味着在调用复制构造函数时它们将被忽略。 Your program is allocating memory for per_2's name and ID, which have dummy values to begin with, then the name is overwritten to be a copy of per_1's name and it's done.您的程序正在为 per_2 的名称和 ID 分配 memory,它们以虚拟值开头,然后将名称覆盖为 per_1 名称的副本,然后就完成了。 In your copy constructor, you also need to specify what the ID should be as well as person::counter or no changes will be made.在您的复制构造函数中,您还需要指定 ID 应该是什么以及person::counter或不进行任何更改。 You could add these two functionalities into a helper method that is called by both the default constructor and the copy constructor for cleaner code, if you wish.如果您愿意,您可以将这两个功能添加到由默认构造函数和复制构造函数调用的辅助方法中,以获得更简洁的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM