复制、移动、交换、赋值和析构函数的C++继承?我需要哪个
C++ Inheritance of copy, move, swap, assignment and destructor? Which do I need
假设我有两个类
Base管理一些内存。它具有工作移动、交换、赋值和析构函数。Derived不会添加任何需要管理的新内容(没有新的内存分配)。
class Base
{
public:
Base();
Base(const Base& other);
friend void swap(Base& a, Base& b);
Base(Base&& other);
protected:
int** some2Darray;
int w, h;
};
class Derived : public Base
{
public:
Derived();
//...?
};
我需要在派生类中实现所有这些函数吗?如何重用基类中的那些函数?在这节课上我不需要管理更多的内存了。
如果我将成员添加到派生类中,这些函数会是什么样子?我应该完全重写所有这些函数吗?或者有没有办法使用例如"复制"基类,并在复制构造函数中额外复制一个添加的成员?
自c++11
以来,您可以继承(编辑:是的,这不是真正的继承,也许应该明确指出)构造函数。通过
class Derived : public Base
{
public:
Derived();
using Base::Base; // <-- this will import constructors
};
但这不会照顾到任何额外的东西!
但是,您不需要复制代码。您可以直接调用父函数。
例如:
class Derived : public Base
{
int extra;
public:
Derived() : Base(), extra(42){};
Derived(const Derived& other) : Base(other) {extra = other.extra;};
void copy(const Derived& other);
friend void swap(Derived& a, Derived& b);
};
void Derived::copy(const Derived& other){
Base::copy(other);
extra = other.extra;
}
另外,不要忘记虚拟析构函数。
编辑:对于交换,我只需要将派生实例强制转换为它们的基,使编译器使用为父类型定义的交换。然后交换多余的东西。
void swap(Derived& a, Derived& b){
swap(static_cast<Base&>(a), static_cast<Base&>(b));
swap(a.extra, b.extra);
}
首先:构造函数、赋值运算符和析构函数是而不是继承的(*)。相反,在某些情况下,编译器可能会自动为您合成。
那么,你什么时候需要写它们呢?仅当default
生成的版本不符合您的需求时:
- 可访问性不是你想要的(它总是
public
) - 方法应为
delete
d default
行为不正确(例如,浅拷贝)- 编译器无法为您合成该方法
关于后两点:
- 三规则规定,如果您编写复制构造函数、复制赋值运算符或析构函数中的任何一个;你也应该提供另外两个
- 在C++11中,如果您编写这3种特殊方法中的任何一种,那么Move构造函数和Move赋值运算符都不会自动合成
- 在C++11中,如果您编写了Move构造函数或Move赋值运算符,那么这三种特殊方法都不会自动合成
(*)C++11名为继承构造函数的功能命名错误,它更像是委派而不是传承。
也就是说,如果Derived
没有任何棘手的属性,那么您可能可以避免编写这些成员。如果您仍然希望编写它们(例如,为了避免内联),您应该能够使用= default
语法:
// Derived.h
class Derived: public Base {
public:
Derived(Derived const&) = default;
Derived& operator(Derived const&);
};
// Derived.cpp
Derived& Derived::operator=(Derived const&) = default;
我不确定move操作符,但您不必实现copy ctor、destructor和copy操作符,因为标准函数会自动从所有基类中调用相应的函数。
编辑:另请参阅如何使用基类';C++中的构造函数和赋值运算符?
相关文章:
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 头文件-继承c++
- 为什么在保护模式下继承升级不起作用
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 混合组合和继承的C++问题
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- C++嵌套if语句,基本货币交换
- 公共与私人继承
- 如何创建从同一类继承的不同对象的向量
- 如何从另一个文件继承私有成员变量和公共函数
- shell排序中的交换和比较
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 带有继承的C++工厂
- 我应该避免多重实现继承吗
- C++继承更改成员
- 私有继承和 ADL 交换
- 复制、移动、交换、赋值和析构函数的C++继承?我需要哪个