提问者:小点点

保存在父类类型向量中时调用派生类函数


我有两个类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类型。在将对象b1保存到AVector中后,有关派生类的所有信息都丢失了吗?我是否可以访问类B中实现的方法?


共1个答案

匿名用户

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

av.at(2).sayHello()

说不通。

也许您来自一种默认使用虚拟方法的语言,比如Java。在C++中不是这样的。

此外,即使您将方法变为虚拟的,它仍然不够好,因为向量只存储类型。您需要存储指向的指针,以便启用多态性并避免对象切片。