简体   繁体   English

复制派生类的构造函数,更改基类

[英]copy constructor for derived class changing base class

Let's assume I have following situation: 假设我有以下情况:

class NamedObject{
public:
    NamedObject(const std::string &name):name_{std::move(name)}{}
private: 
    const std::string name_;
}

class Person: public NamedObject{
public:
    Person(const std::string &name, int age): NamedObject(name), age_{age}{}
private:
    int age_;
}

I want to create a "copy constructor" where I copy all members from Person but change the name (for whatever reason). 我想创建一个“复制构造函数”,在其中复制Person所有成员,但更改名称(无论出于何种原因)。

class Person: public NamedObject{
public:
    Person(const std::string &name, int age): NamedObject(name), age_{age}{}
    Person(const std::string &newName, const Person &other): NamedObject(name){
        age_ = other.age;
    }
private:
    int age_;
}

Now assume I have not only one attribute like age but many attributes and they are changed a lot during development. 现在假设我不仅具有age属性,而且具有许多属性,并且它们在开发过程中发生了很大变化。 Is it somehow easily possible to create a function like Person(const std::string &newName, const Person &other) without manually copying all attributes like age_ = other.age; 是否可以轻松地创建类似Person(const std::string &newName, const Person &other)而无需手动复制age_ = other.age;等所有属性age_ = other.age; . The idea is that during development I do not have to always recall to change this constructor if I add a new attribute. 想法是,在开发过程中,如果添加新属性,则不必总是记得要更改此构造函数。

Please note that I cannot simply change the name because it is const . 请注意,我不能简单地更改名称,因为它是const

You could define an assignment operator on NamedObject that does nothing. 您可以在NamedObject上定义什么都不做的赋值运算符。 Then you would be able to use *this = other in the "copy constructor": 然后,您将可以在“复制构造函数”中使用*this = other

class NamedObject{
public:
    NamedObject(const std::string &name):name_{name}{}
    NamedObject &operator= (const NamedObject &) {
        return *this;
    }
    const std::string name_;
};


class Person: public NamedObject{
public:
    Person(const std::string &name, int age): NamedObject(name), age_{age}{}
    Person(const std::string &newName, const Person &other): NamedObject(newName){
        *this = other;
    }
    int age_;
};

Live example: https://onlinegdb.com/rJ4J5oy3M 实时示例: https//onlinegdb.com/rJ4J5oy3M

Why it works: 工作原理:

C++ will automatically define a copy assignment operator for eligible classes (check the following link for details on what eligible means). C ++将自动为符合条件的类定义一个副本分配运算符(请查看以下链接,详细了解符合条件的含义)。 From cppreference : 来自cppreference

If the implicitly-declared copy assignment operator is neither deleted nor trivial, it is defined (that is, a function body is generated and compiled) by the compiler if odr-used. 如果隐式声明的副本赋值运算符既不删除也不琐碎,则在使用odr时由编译器定义(即生成并编译函数体)。 For union types, the implicitly-defined copy assignment copies the object representation (as by std::memmove). 对于联合类型,隐式定义的副本分配会复制对象表示形式(如std :: memmove所示)。 For non-union class types (class and struct), the operator performs member-wise copy assignment of the object's bases and non-static members, in their initialization order, using built-in assignment for the scalars and copy assignment operator for class types. 对于非联合类类型(类和结构),运算符使用标量的内置赋值和类类型的复制赋值运算符,按其初始化顺序对对象的基础和非静态成员执行成员级的成员复制赋值。

Thus, for your example the implicitly defined copy assignment operator (the one that is called when we do *this = other; ) will be defined as follows: 因此,对于您的示例,隐式定义的副本赋值运算符(当我们执行*this = other;时调用的那个)将定义如下:

  • it will use the copy assignment operator of NamedObject to copy the base class (which we defined to do nothing, so it won't copy name_ ), 它将使用NamedObject的复制赋值运算符复制基类(我们定义为不执行任何操作,因此不会复制name_ ),
  • it will use the copy assignment operator for age_ and any additional member you add to the class. 它将使用age_和您添加到该类中的任何其他成员的副本分配运算符。

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

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