创建子类以影响另一个子类

时间:2018-02-20 18:28:38

标签: c++ polymorphism virtual

我正在使用的库定义了一个抽象基类A,其中包含~10个纯虚方法。没有公开定义的非纯方法,我怀疑A没有私有数据,即类只是一个接口。该库还定义了一些A的具体子类,例如C

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

相反,我已经定义了一个新的B子类。这个子类不是具体的,A的所有纯虚方法都是孤立的。它定义了一些新的辅助方法,它们调用A定义的方法。 B也没有定义任何字段。

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

  1. 在堆上创建类型为C的对象。
  2. 将指向此对象的指针转换为B*类型。
  3. 返回此指针,退出创建对象的本地范围。
  4. 使用此指针在不同的范围内调用B定义的方法。
  5. 这样安全吗?对象是在堆上创建的,所以我认为不会发生任何切片。如果安全性取决于AC定义的字段,那么需要哪些要求来保证此行为?

    如果AC都没有自己的数据而不是vpointer,这会安全吗?

    如果C只有自己的数据呢?

    编辑:我应该补充一点,我尝试过这种行为至少似乎是我想要的行为。我没有描述内存泄漏。

2 个答案:

答案 0 :(得分:1)

整个事情看起来像代码味道给我。我将采用包装类的B类方法:在构造函数中获取A *指针,将所需的调用转发给A *。然后你可以将C *传递给那个构造函数,它将通过B析构函数中的“delete”正确删除。

答案 1 :(得分:0)

以下是关于我的评论的一个想法。它的行为符合预期,可能是一些隐藏的危险,但对我来说,只要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();
}