Reputation: 11002
Is there a way to specify a default initializer for a base class in the class declaration?
Say I have:
#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};
};
Is there a way to specify a default base initializer similar to the default member initializer?
Something like perhaps:
#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};
};
I thought about using delegating constructors, but if there are multiple bases and different constructors where the same bases are not always default initialized then delegating constructors wouldn't help to simplify in the same way as a constructor member initializer list would do for members.
Upvotes: 0
Views: 65
Reputation: 595961
Is there a way to specify a default initializer for a base class in the class declaration?
To do that in the class declaration itself would require making the base class have a template parameter, eg:
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};
};
But that means Animal<6>
and Animal<8>
are different class types, and you won't be able to pass around Ant
and Spider
objects where Animal
is expected (without using more templates, that is).
That being said, assuming you actually want Animal
to be a distinct class you can derive from and pass around, I suggest you could give your int
constructors default values and omit the = default
constructors (and yes, you can use delegating constructors in this example), eg:
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;
};
Upvotes: 3