【问题标题】:C++ Class Design/ Excluding Base Class membersC++ 类设计/不包括基类成员
【发布时间】:2021-02-26 17:38:28
【问题描述】:

假设我刚刚创建了一个名为 Base 的类,其中包含 2 或 3 个成员,就是这样:

class Base
{
private:
    std::string name;
    std::string  number;
public:
    virtual std::string  get() const;
    virtual void set();
//...
};

在下一步中,我想从这个类中创建一些派生类。但在某些派生类中,我不需要基类的所有成员。

如何在派生类中排除基类的某些成员而保留其他成员?

例如:

class Derived_One : public Base {
private:
    std::string wight;
    int A;
public:
    //...
};

我只想保留基类的第一个属性 (std::string name) 并删除第二个属性 std::string number。如何在派生类Drive_One中排除它?

我正在寻找一种优雅的解决方案来应对这种变化或我还不知道的广为人知的设计模式。

【问题讨论】:

  • 您根本不需要name 成员,还是想要自己的覆盖?或者只是阻止通过get() 进行公共访问?
  • 你不能。假设您将Drived_one 对象传递给接受Base 参数的函数foo()foo() 可以访问Base 对象的number 成员。如果删除派生类的成员,就会破坏 C++ 基/派生多态性。
  • 如果派生类不需要基类拥有的东西,那么它不应该从它派生。这表明您的基类至少做了两个正交的事情,这对于单个类来说已经太多了
  • 但是解决方案是什么?只是编写几个独立的类,尽管其中一些代码是特别相同的?
  • 上下文太少。解决什么?在BaseDerived_One 不想从Base 继承的情况下,解决方案是不要从Base 继承;)。继承不是解决一切的办法。只选择一些成员来继承是不可能的

标签: c++ c++20


【解决方案1】:

如果您的派生类只需要一些基类,则表明基类应该一分为二。一个类派生自另一个类或两个单独的类。

第一种情况的一个例子可能是这样的:

class Base_One
{
private:
    std::string name;
public:
//...
};

class Base_Two : public Base_One
{
private:
    std::string number;
public:
//...
};

class Derived_One : public Base_One
{
private:
    std::string wight;
    int A;
public:
    //...
};

class Derived_Two : public Base_Two
...

在第二种情况下(如果 Base_Two 派生自 Base_One 没有意义),Base_OneBase_Two 将是单独的类,派生类将派生自其中之一或两者,即上面的例子将被修改如下:

class Base_Two
{
private:
    std::string number;
public:
//...
};

...

class Derived_Two : public Base_One, public Base_Two
...

【讨论】:

    【解决方案2】:

    派生类我不需要基类的所有成员。

    简单地说:这不是一个通用的基类!

    做什么:

    选项 1) 将基类拆分为多个,并创建线性层次结构。

    但这可能会导致您的设计变得复杂,特别是如果从层次结构中不同类的不同成员交叉调用感觉很自然。

    选项 2) 如果您的设计因简单地拆分为线性层次结构而变得更加复杂,您应该给CRTP 一个机会。

    这可以将特殊功能注入到类层次结构中并保持设计更简洁。不好的一面是,这可能会导致大量模板实例浪费内存。您的设计更易于维护,但您可能会付出更高的内存消耗。

    某些代码行无法即时回答最适合您的设计的内容。只需尝试了解这两种选择并做出决定。也许你以后会改变它。

    【讨论】:

      猜你喜欢
      • 2011-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-27
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多