默认基类初始值设定项

Default base class initializer

本文关键字:基类 默认      更新时间:2023-10-16

有没有办法在类声明中为基类指定默认初始值设定项?

假设我有:

#include <string>
struct Animal {
    Animal(int legs) : legs{legs} {}
    Animal() = default;
    int legs{4};
};
struct Ant : Animal {
    Ant(int size)       : Animal{6}, size{size} {}
    Ant()               : Animal{6} {}
    Ant(std::string s)  : Animal{6} {}
    int size{0};
};
struct Spider : Animal {
    Spider(int size)       : Animal{8}, size{size} {}
    Spider()               : Animal{8} {}
    Spider(std::string s)  : Animal{8} {}
    int size{0};
};

有没有办法指定类似于默认成员初始值设定项的默认基初始值设定项

也许像这样:

#include <string>
struct Animal {
    Animal(int legs) : legs{legs} {}
    Animal() = default;
    int legs{4};
};
struct Ant : Animal{6} {
    Ant(int size)       : size{size} {}
    Ant()                {}
    Ant(std::string s)   {}
    int size{0};
};
struct Spider : Animal{8} {
    Spider(int size)       : size{size} {}
    Spider()                {}
    Spider(std::string s)   {}
    int size{0};
};
我想过使用委托构造函数,

但如果有多个基和不同的构造函数,其中相同的基并不总是默认初始化,那么委托构造函数将无助于简化,就像构造函数成员初始值设定项列表对成员所做的那样。

有没有办法在类声明中为基类指定默认初始值设定项?

要在类声明本身中执行此操作,需要使基类具有模板参数,例如:

template <size_t NumberOfLegs>
struct Animal {
    Animal() = default;
    int legs{NumberOfLegs};
};
struct Ant : Animal<6> {
    Ant()               = default;
    Ant(int size)       : size{size} {}
    Ant(std::string s)  {}
    int size{0};
};
struct Spider : Animal<8> {
    Spider()               = default;
    Spider(int size)       : size{size} {}
    Spider(std::string s)  {}
    int size{0};
};

但这意味着Animal<6>Animal<8>是不同的类类型,您将无法在预期Animal的地方传递AntSpider对象(也就是说,不使用更多模板(。

话虽如此,假设您实际上希望Animal是一个可以从中派生和传递的独特类,我建议您为int构造函数提供默认值并省略= default构造函数(是的,您可以在此示例中使用委托构造函数(,例如:

struct Animal {
    Animal(int legs = 4) : legs{legs} {}
    int legs;
};
struct Ant : Animal {
    Ant(int size = 0)   : Animal{6}, size(size) {}
    Ant(std::string s)  : Ant(0) {}
    int size;
};
struct Spider : Animal {
    Spider(int size = 0)   : Animal{8}, size{size} {}
    Spider(std::string s)  : Spider(0) {}
    int size;
};