假设我有两个班级
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类,那么这些函数会是什么样子?我是否应该完全重写所有这些函数,或者是否有某种方法可以使用例如“复制”基类,只是在复制构造函数中复制一个添加的成员?
答案 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特性名称不详,它比继承更委托。
话虽如此,如果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++?