C ++复制,移动,交换,赋值和析构函数的继承?我需要哪个

时间:2013-12-15 12:15:15

标签: c++ inheritance

假设我有两个班级

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();
    //...?
};

我是否需要在派生类中实现所有这些函数才能使它更好?如何从基类重用这些函数?我不需要在这个类中管理更多的内存。

如果我将成员添加到Derived类,那么这些函数会是什么样子?我是否应该完全重写所有这些函数,或者是否有某种方法可以使用例如“复制”基类,只是在复制构造函数中复制一个添加的成员?

3 个答案:

答案 0 :(得分:4)

你可以继承(编辑:是的,这不是真正的继承,也许这应该明确注明)自c++11以来的构造函数。通过

class Derived : public Base
{
public:
    Derived();
    using Base::Base; // <-- this will import constructors
};

但这不会照顾任何额外内容!

但是,您不需要复制代码。你可以调用父函数。

E.g:

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

另外不要忘记虚拟析构函数。

编辑: 对于swap,我只是将派生实例强制转换为它们的基础,以使编译器使用为父类型定义的交换。然后换掉额外的东西。

void swap(Derived& a, Derived& b){
    swap(static_cast<Base&>(a), static_cast<Base&>(b));
    swap(a.extra, b.extra);
}

答案 1 :(得分:2)

首先:构造函数,赋值运算符和析构函数继承(*)。相反,它们在某些情况下可能由编译器自动合成

那么,什么时候需要写它们?仅当default生成的版本不符合您的需求时:

  • 可访问性不是您想要的(它总是public
  • 方法应为delete d
  • default行为不正确(例如浅拷贝)
  • 编译器无法为您合成该方法

关于后两点:

  • 三规则指出,如果您编写复制构造函数,复制赋值运算符或析构函数中的任何一个;你应该提供其他两个
  • 在C ++ 11中,如果您编写了这3种特殊方法中的任何一种,则不会自动合成移动构造函数和移动赋值运算符
  • 在C ++ 11中,如果你编写了移动构造函数或移动赋值运算符,那么这三种特殊方法都不会自动合成

(*)名为继承构造函数的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;

答案 2 :(得分:1)

我不确定move运算符,但是你不必实现copy ctor,析构函数和复制运算符,因为标准函数会自动从所有基类调用相应的函数。

编辑:另见How to use base class's constructors and assignment operator in C++?