Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;复制、移动、交换、赋值和析构函数的继承?我需要什么_C++_Inheritance - Fatal编程技术网

C++ C++;复制、移动、交换、赋值和析构函数的继承?我需要什么

C++ C++;复制、移动、交换、赋值和析构函数的继承?我需要什么,c++,inheritance,C++,Inheritance,假设我有两门课 Base管理一些内存。它具有工作移动、交换、赋值和析构函数。 派生不添加任何需要管理的新内容(无新内存分配) 我需要在派生类中实现所有这些函数吗?如何从基类重用这些函数?我不需要在这个类中管理更多的内存 若我将成员添加到派生类中,那个么这些函数会是什么样子?我是否应该完全重写所有这些函数,或者是否有某种方法可以使用,例如“复制”基类,并在复制构造函数中额外复制一个添加的成员?我不确定移动运算符,但您不必实现复制构造函数,析构函数和复制运算符作为标准函数将自动从所有基类调用相应的函

假设我有两门课

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

我需要在派生类中实现所有这些函数吗?如何从基类重用这些函数?我不需要在这个类中管理更多的内存


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

我不确定移动运算符,但您不必实现复制构造函数,析构函数和复制运算符作为标准函数将自动从所有基类调用相应的函数


编辑:另请参见

我不确定move运算符,但您不必实现copy-ctor、destructor和copy-operator,因为标准函数将自动从所有基类调用相应的函数

编辑:另请参见您可以继承(编辑:是的,这不是真正的继承,可能需要明确指出)构造函数,因为
c++11
。通过

class Derived : public Base
{
public:
    Derived();
    using Base::Base; // <-- this will import constructors
};
也不要忘记虚拟析构函数

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

void swap(Derived& a, Derived& b){
    swap(static_cast<Base&>(a), static_cast<Base&>(b));
    swap(a.extra, b.extra);
}
无效掉期(衍生a、衍生b){
交换(静态广播(a)、静态广播(b));
互换(a.额外,b.额外);
}
您可以继承(编辑:是的,这不是真正的继承,可能需要明确指出)构造函数,因为
c++11
。通过

class Derived : public Base
{
public:
    Derived();
    using Base::Base; // <-- this will import constructors
};
也不要忘记虚拟析构函数

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

void swap(Derived& a, Derived& b){
    swap(static_cast<Base&>(a), static_cast<Base&>(b));
    swap(a.extra, b.extra);
}
无效掉期(衍生a、衍生b){
交换(静态广播(a)、静态广播(b));
互换(a.额外,b.额外);
}

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

那么,你什么时候需要写?仅当生成的
默认版本不符合您的需要时:

  • 可访问性不是您想要的(它总是
    公共的
  • 方法应该是
    delete
    d
  • 默认值
    行为不正确(例如,浅拷贝)
  • 编译器无法为您合成该方法
关于后两点:

  • 三条规则规定,如果您编写复制构造函数、复制赋值运算符或析构函数中的任何一个;你也应该提供另外两个
  • 在C++11中,如果您编写了这三种特殊方法中的任何一种,那么不会自动合成Move构造函数和Move Assignment操作符
  • 在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;

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

那么,你什么时候需要写?仅当生成的
默认版本不符合您的需要时:

  • 可访问性不是您想要的(它总是
    公共的
  • 方法应该是
    delete
    d
  • 默认值
    行为不正确(例如,浅拷贝)
  • 编译器无法为您合成该方法
关于后两点:

  • 三条规则规定,如果您编写复制构造函数、复制赋值运算符或析构函数中的任何一个;你也应该提供另外两个
  • 在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;

它必须是继承吗?组成不起作用吗?如果您只想
Derived
访问由
Base
管理的资源,只需向
Derived
添加一个
Base
成员即可。这看起来像是一个经典。它必须是继承吗,组合不起作用吗?如果您只想
Derived
访问
Base
管理的资源,只需将
Base
成员添加到
Derived
。这看起来像是一个经典的感谢。这就是我要找的。还有一件事。如果我在派生中没有任何额外的成员,我必须声明复制构造函数吗?或者我可以信任编译器从基类调用一个吗?再问一个问题,我就接受了。交换功能呢