Lets say I have a class A
that has a member of type int
.
I have a class B
which is a subclass of A
.
B
is meant to initialize the members to some state and has no other purpose.
#include <string>
#include <iostream>
struct A {
int someInt;
A() : someInt(33){}
};
struct B : public A {
B() {
someInt = 4;
}
};
int main() {
A a = A();
A b = B();
std::cout<< a.someInt << std::endl;
std::cout << b.someInt << std::endl;
}
Notice how I use A b = B()
where object slicing should occur.
However since B
doesn't add anything to A
, is it a valid alternative to using A
with different constructor parameters (or any other form of creating instances of A
)?
Edit: The background is that I have a class that has some complex setup. Putting the initialization into separate child class is way easier than lets say write a constructor, factory or builder.
To answer your question as directly as possible, what you're doing is certainly "valid" in the sense that it will compile and run and produce a correct result. It's probably not the most common way to accomplish this though.
My recommendation for a more idiomatic approach would be to use a common base class and templatize all of your derived versions. Basically make the compiler do the work of setting the integer value you want.
struct ABase {
int someInt;
ABase() = delete;
ABase(int initVal) : someInt(initVal) { }
};
template<int T>
struct A : public ABase {
A() : ABase(T) {}
};
int main() {
ABase a = A<33>();
ABase b = A<4>();
std::cout << a.someInt << std::endl;
std::cout << b.someInt << std::endl;
}
This is probably less code overall (especially if you have more than just two versions of this class), and much more flexible.