假设我有以下情况:
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;
。这个想法是,在开发过程中,如果我添加了新属性,则不必总是记得要更改此构造函数。
请注意,我不能简单地更改名称,因为它是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_
以及您添加到该类的任何其他成员。本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句