避免复制子类中的所有构造函数

Avoid copying all constructors in subclasses

本文关键字:构造函数 复制 子类      更新时间:2023-10-16

所以一个基类有多个构造函数:

sf::Sprite()
sf::Sprite(const Texture& texture)
sf::Sprite(const Texture& texture, const IntRect& rectangle)

我多次对这个类进行子类化:

class Sub : public sf::Sprite {
public:
Sub() : sf::Sprite() {};
Sub(const Texture& texture) : sf::Sprite(texture) {};
Sub(const Texture& texture, const IntRect& rectangle) : sf::Sprite(texture, rectangle) {};
// My subclass specific code
};

如您所见,我必须为每个子类重复这三个构造函数。有没有办法避免这种情况,因为构造函数通常不做任何特殊的事情?有时不过,我需要一些特定于类的初始化,因此直接复制所有内容并不总是可行的。

您可以通过继承构造函数来实现此目的(自 C++11 起)。

如果 using-声明引用所定义的类的直接基的构造函数(例如using Base::Base;),在初始化派生类时,该基的所有构造函数(忽略成员访问)都对重载解析可见。

例如

class Sub : public sf::Sprite {
public:
using sf::Sprite::Sprite;
// My subclass specific code
};

如果使用继承的构造函数来初始化Sub,则使用继承的构造函数初始化sf::Sprite子对象,并且Sub的所有其他成员都像由默认的默认构造函数一样进行初始化。

如果有一些特殊情况需要处理,你仍然可以在Sub中定义构造函数,具有相同签名的继承构造函数将被隐藏。

与任何其他非静态成员函数的 using 声明一样,如果继承的构造函数与派生函数之一的签名匹配,则派生中的版本将隐藏该构造函数,使其在查找中隐藏。

可以使用using关键字继承基类的构造函数,不包括特殊构造函数(默认、复制、移动)。要缩短默认构造函数,只需使用= default即可。如果你想要特定于类的初始化,你可以简单地再次编写构造函数,就像你现在所做的那样。

class Sub : public sf::Sprite {
public:
Sub() = default;
using sf::Sprite::Sprite;
Sub(const Texture& texture) 
{
// your custom code.
};
// My subclass specific code
};

如果您可以"继承"构造函数,即拥有一个具有完全相同参数的构造函数,只需按照其他答案中的说明使用using。但是,如果derived类的构造函数具有其他参数和/或需要某些特定于类的初始化,则可以使用可变参数模板。

struct base
{
base(int);
base(std::string const&);
base(some_type const&);
base(std::string const&, some_type const&);
/* ... */
};
struct derived : base
{
template<typename...Args>
derived(some_other_type const&x, Args&&...args)
: base(std::forward<Args>(args)...)
, private_datum(x)
{
construction_details();          // class-specific initialisation
}
private:
some_other_type private_datum;
void construction_details();       // implemented in source code
};