创建一个子类影响另一个子类的行为

Creating a subclass to affect the behavior of another subclass

本文关键字:子类 影响 另一个 一个 创建      更新时间:2023-10-16

我正在使用的库定义了一个抽象的基类A,使用〜10个纯虚拟方法。没有公开定义的非PURE方法,我怀疑A没有私人数据,即类只是一个接口。该库还定义了一些A的混凝土子类,例如C

我想向A添加一些功能,以便其所有子类继承此功能。但是,库中定义了 A,我不能这样做。

相反,我定义了一个新的B子类。该子类不是具体的,并且A的所有纯虚拟方法都是单独的。它定义了一些新的助手方法,这些方法呼吁A定义的方法。B也没有定义的字段。

为了使用B来增强C实例的功能,我已经完成了以下操作,我怀疑不能保证行为。

  1. 在堆上创建类型C的对象。
  2. 将指向此对象的指针铸造为类型B*
  3. 返回此指针,退出创建对象的本地范围。
  4. B使用此指针在其他范围中定义的呼叫方法。

这是安全的吗?这些对象是在堆上创建的,因此我认为不会发生任何切片。如果安全性取决于AC定义哪些字段,则需要哪些要求保证此行为?

如果AC都没有自己的数据以外的其他数据,这会安全吗?

如果只有C有自己的数据,那怎么办?

编辑:我应该补充一点,我已经尝试过,并且行为至少似乎是我想要的。我尚未介绍记忆泄漏。

整个过程对我来说看起来像是代码的气味。我将采用包装班的B类的方法:在构造函数中取A*指针,将您需要的调用转发到A*。然后,您可以将C*传递给该构造函数,该构造函数将通过B destructor中的"删除"正确删除。

这是我评论的一个想法。它的行为按预期的是,可能是一些隐藏的危险,但对我而言,只要bar不容纳任何数据,这似乎是合理的。

#include <iostream>
struct base {
    int x = 1;
    int y = 2;
    void show() {
        std::cout << x + y << std::endl;
    }
    virtual void virt() = 0;
};
struct foo : base {
    int a = 5;
    int b = 2;
    void print() {
        std::cout << a + b << std::endl;
        x++;
    }
    void virt() override {
        std::cout << "foo" << std::endl;
    }
};
template <typename T>
struct bar : T {
    void print2() {
        std::cout << T::a * T::b << std::endl;
        T::b++;
        T::x++;
        T::virt();
    }
};
template <typename Base>
bar<Base>* extend_with_bar(Base& base) {
    return static_cast<bar<Base>*>(&base);
}
int main() {
    foo f;
    f.show();
    f.print();
    auto b = extend_with_bar(f);
    b->print2();
    b->print2();
    b->print();
    f.print();
    b->show();
    f.show();
    b->virt();
}