c++object-slicing

Are subclasses that only change the members valid practice?


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.


Solution

  • 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.