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

Mar*_*nen 20 c++ inheritance constructor

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

sf::Sprite()
sf::Sprite(const Texture& texture)
sf::Sprite(const Texture& texture, const IntRect& rectangle)
Run Code Online (Sandbox Code Playgroud)

我多次将这个类子类化:

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
};
Run Code Online (Sandbox Code Playgroud)

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

son*_*yao 34

您可以通过继承构造函数来实现这一点(从C++ 11开始).

如果using声明引用了正在定义的类的直接基础的构造函数(例如using Base::Base;),那么在初始化派生类时,该基础的所有构造函数(忽略成员访问)都会变得可见以重载解析.

例如

class Sub : public sf::Sprite {
    public:
        using sf::Sprite::Sprite;

        // My subclass specific code
};
Run Code Online (Sandbox Code Playgroud)

如果继承的构造函数用于初始化a Sub,sf::Sprite则使用继承的构造函数初始化子对象,并且初始化所有其他成员,Sub就像默认的默认构造函数一样.

如果需要处理某些特殊情况,您仍然可以定义构造Sub函数,将隐藏具有相同签名的继承构造函数.

与任何其他非静态成员函数的using声明一样,如果继承的构造函数与Derived的其中一个构造函数的签名匹配,则它将被Derived中的版本隐藏.

  • @MarkusMeskanen回答修订.如果我理解正确,如果需要,你仍然可以在`Sub`中提供构造函数. (2认同)

Seb*_*ern 15

您可以使用该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
};
Run Code Online (Sandbox Code Playgroud)


Wal*_*ter 7

如果你可以'继承'构造函数,即有一个具有完全相同的参数,只需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
};
Run Code Online (Sandbox Code Playgroud)