首页 > 解决方案 > 保存在父类类型向量中时调用派生类函数

问题描述

我有两个类 A 和 B 以及一个类 AVector 来存储类 A 的对象和从类 A 派生的类。

#include <iostream>
#include <vector>

class A {
    private:
        int id_;

    public:
        A(int id);
        int id() { return id_; }
};

A::A(int id) : id_{id} {}

class B : public A {
    private:

    public:
        B(int id);
        std::string sayHello() { return "Hello"; }
};

B::B(int id) : A(id) {}

class AVector : private std::vector<A> {
    private:

    public:
        void push_back(const A& inv);
        using std::vector<A>::size;
        using std::vector<A>::at;
        using std::vector<A>::begin;
        using std::vector<A>::end;
};

void AVector::push_back(const A& a) {
    std::vector<A>::push_back(a);
}

int main()
{
    A a1(3);
    A a2(8);
    B b1(12);
    std::cout << b1.sayHello() << std::endl; // Hello

    AVector av;
    av.push_back(a1);
    av.push_back(a2);
    av.push_back(b1);

//    std::cout << "id b1 = " << (av.at(2)).sayHello() << std::endl; // error
// main.cpp: In function ‘int main()’:
// main.cpp:54:43: error: ‘__gnu_cxx::__alloc_traits >::value_type {aka class A}’ has no member named ‘sayHello’
//     std::cout << "id b1 = " << (av.at(2)).sayHello() << std::endl; // error
    A *a_ref = &(av.at(1));
    std::cout << "id a_ref(a1) = " << a_ref->id() << std::endl; // id a_ref(a1) = 8
//    B *b_ref = &(av.at(2)); // error
// main.cpp: In function ‘int main()’:
// main.cpp:60:16: error: invalid conversion from ‘__gnu_cxx::__alloc_traits >::value_type* {aka A*}’ to ‘B*’ [-fpermissive]
//      B *b_ref = &(av.at(2)); // error
}

将 B 类型的对象放入 AVector 后,我无法将其转换回 B 类型。在 AVector 中保存对象 b1 后,有关派生类的所有信息是否都丢失了,我能否以某种方式访问​​在 B 类中实现的方法?

标签: c++

解决方案


向量的对象具有类型A。根本没有B。所以这样做:

av.at(2).sayHello()

没有意义。

也许您来自默认使用虚拟方法的语言,例如 Java。在 C++ 中情况并非如此。

另外,即使你把方法弄虚了,还是不够好,因为vector只存储A类型。您需要存储指针以A启用多态性并避免对象切片。


推荐阅读