繁体   English   中英

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

[英]copy constructor for derived class changing base class

假设我有以下情况:

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_;
}

我想创建一个“复制构造函数”,在其中复制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_;
}

现在假设我不仅具有age属性,而且具有许多属性,并且它们在开发过程中发生了很大变化。 是否可以轻松地创建类似Person(const std::string &newName, const Person &other)而无需手动复制age_ = other.age;等所有属性age_ = other.age; 想法是,在开发过程中,如果添加新属性,则不必总是记得要更改此构造函数。

请注意,我不能简单地更改名称,因为它是const

您可以在NamedObject上定义什么都不做的赋值运算符。 然后,您将可以在“复制构造函数”中使用*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_;
};

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

工作原理:

C ++将自动为符合条件的类定义一个副本分配运算符(请查看以下链接,详细了解符合条件的含义)。 来自cppreference

如果隐式声明的副本赋值运算符既不删除也不琐碎,则在使用odr时由编译器定义(即生成并编译函数体)。 对于联合类型,隐式定义的副本分配会复制对象表示形式(如std :: memmove所示)。 对于非联合类类型(类和结构),运算符使用标量的内置赋值和类类型的复制赋值运算符,按其初始化顺序对对象的基础和非静态成员执行成员级的成员复制赋值。

因此,对于您的示例,隐式定义的副本赋值运算符(当我们执行*this = other;时调用的那个)将定义如下:

  • 它将使用NamedObject的复制赋值运算符复制基类(我们定义为不执行任何操作,因此不会复制name_ ),
  • 它将使用age_和您添加到该类中的任何其他成员的副本分配运算符。

暂无
暂无

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

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