仅更改成员的子类是否有效?

Are subclasses that only change the members valid practice?

假设我有一个 class A,它有一个 int 类型的成员。 我有一个 class B,它是 A 的子 class。 B 用于将成员初始化为某种状态,没有其他目的。

#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;
}

请注意我如何使用 A b = B() 应该发生对象切片的地方。 然而,由于 B 不会向 A 添加任何内容,它是否是使用具有不同构造函数参数的 A 的有效替代方案(或任何其他创建 A 实例的形式) ?

编辑: 背景是我有一个 class 有一些复杂的设置。 将初始化放入单独的子 class 比让我们说写一个构造函数、工厂或构建器要容易得多。

更常见且不易出错的方法是定义静态方法来创建您的 class 实例:

struct A {
    static A makeA();
    static A makeB();
};

int main()
{
    auto a = A::makeA();
    auto b = A::makeB();
}

并且为了防止更多错误,您可能希望直接禁止创建 A 的实例,而不是通过将 A ctor 设为私有来禁止创建静态方法集。

作为更好的做法,
在 class A 中使用另一个构造函数,此构造函数将采用参数 在 class A 中使用单独的函数来执行您想要的操作。

并且关于 “将初始化放入单独的子 class 比让我们说写一个构造函数、工厂或构建器要容易得多” 在这方面没有意义情况,所以即使代码像你说的那样复杂也不容易。

为了尽可能直接地回答您的问题,您所做的肯定是“有效的”,因为它将编译 运行 并产生正确的结果。不过,这可能不是最常用的方法。

我建议采用更惯用的方法是使用通用基础 class 并对所有派生版本进行模板化。基本上让编译器完成设置你想要的整数值的工作。

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;
}

这可能是总体上更少的代码(特别是如果你有不止两个版本的这个class),而且更灵活。