繁体   English   中英

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

[英]C++ Inheritance of copy, move, swap, assignment and destructor? Which do I need

假设我有两个班

Base管理一些内存。 它具有工作移动,交换,分配和析构函数。 派生不添加任何需要管理的新内容(无需新的内存分配)。

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类中,这些函数将如何显示? 我应该完全重写所有这些功能,还是应该使用某种方法来使用例如“复制”基类,并仅在复制构造函数中复制该添加的成员?

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 Constructor和Move Assignment Operator
  • 在C ++ 11中,如果编写了Move构造函数或Move赋值运算符,则这3种特殊方法都不会自动合成

(*)称为继承构造函数的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 ++中使用基类的构造函数和赋值运算符?

暂无
暂无

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

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