C++ 从转换为基类指针的实例访问子类的方法

C++ 从转换为基类指针的实例访问子类的方法,c++,polymorphism,C++,Polymorphism,我有两个类A和B,它们来自同一个基类base。 我主要定义了一个向量Base*,我使用它来存储a和B中的元素。 使用reinterpret_cast,我能够调用它们真正类的方法。 这个密码安全吗?有没有更好的/标准的方法 实代码中的两个类共享基类中的大多数方法,但是A拥有一些与base或B不共享的方法,而B也有相同的方法,因此虚拟不是一个选项 #include <iostream> #include <vector> class Base { }; class A :

我有两个类
A
B
,它们来自同一个基类
base
。 我主要定义了一个向量
Base*
,我使用它来存储
a
B
中的元素。 使用reinterpret_cast,我能够调用它们真正类的方法。 这个密码安全吗?有没有更好的/标准的方法

实代码中的两个类共享基类中的大多数方法,但是
A
拥有一些与
base
B
不共享的方法,而
B
也有相同的方法,因此虚拟不是一个选项

#include <iostream>
#include <vector>

class Base {
};

class A : public Base {
public:
    void print_from_A() {
        std::cout << "hello from A\n";
    }
};

class B : public Base {
public:
    int number;
    void read_from_B() {
        std::cin >> number;
    }
};

int main(int argc, char * argv[]) {
    std::vector<Base*> v;
    v.push_back(new A());
    v.push_back(new B());

    (reinterpret_cast<A *>(v[0]))->print_from_A();
    (reinterpret_cast<B *>(v[1]))->read_from_B();

    for(auto && e: v) {
        delete e;
    }
    return 0;
}
#包括
#包括
阶级基础{
};
A类:公共基地{
公众:
从_A()作废打印_{
std::cout>number;
}
};
int main(int argc,char*argv[]){
std::向量v;
v、 向后推(新的A());
v、 向后推(新B());
(重新解释)

似乎正确的方法是使用
静态\u cast

这就是答案吗

有没有更好的/标准的方法

  • 最好使用
    虚拟
    成员函数

  • 如果无法使用
    虚拟
    成员函数,请执行
    动态_cast
    ,检查强制转换的状态,并仅在强制转换成功时调用成员函数

  • 请注意,基类需要有一个
    virtual
    成员函数才能运行
    dynamic\u cast
    。在这种情况下,建议至少将析构函数设置为
    virtual
    成员函数

    以下是使用
    virtual
    成员函数的程序的更新版本:

    #include <iostream>
    #include <vector>
    
    class Base {
       public:
          virtual ~Base() {}
          virtual void print() const = 0;
          virtual void read() = 0;
    };
    
    class A : public Base {
    public:
        virtual void print() const {
            std::cout << "hello from A\n";
        }
       virtual void read() 
       {
          // Nothing to do.
       }
    };
    
    class B : public Base {
    public:
        int number;
        virtual void print() const {
            std::cout << "hello from B, " << number << "\n";
        }
        virtual void read() {
            std::cin >> number;
        }
    };
    
    int main(int argc, char * argv[]) {
        std::vector<Base*> v;
        v.push_back(new A());
        v.push_back(new B());
    
        v[0]->read();
        v[0]->print();
        v[1]->read();
        v[1]->print();
    
        for(auto && e: v) {
            delete e;
        }
        return 0;
    }
    
    #包括
    #包括
    阶级基础{
    公众:
    虚拟~Base(){}
    虚空打印()常量=0;
    虚空读取()=0;
    };
    A类:公共基地{
    公众:
    虚空打印()常量{
    std::cout print();
    v[1]->read();
    v[1]->print();
    用于(自动和e:v){
    删除e;
    }
    返回0;
    }
    
    将虚拟析构函数添加到
    Base
    ,使用
    dynamic\u cast
    进行向下投射,尝试不进行向下投射。使用
    dynamic\u cast
    我得到错误“Base”不是polymorphic@Nisba,基类需要有一个
    virtual
    成员函数才能运行
    dynamic\u cast
    。在这种情况下,建议我想让析构函数至少成为一个
    虚拟的
    成员函数。它工作得很好!附加问题:它是否也能与智能指针一起工作?我发现有一个标准的方法可以做到这一点:@Nisba,是的,它能与智能指针一起工作,正如你已经发现的那样。