从派生类c ++获取变量

Dav*_*ass 2 c++ oop class derived

我希望只有在类是特定的派生类时才能做某事.那就是我:

class X{
    int id;
}

class A: public X{
    void run();
}

class B: public X{
    int lala;
}
Run Code Online (Sandbox Code Playgroud)

我想做一些事情:

main(){
    vector<X *> types;
    types.push_back(new A);
    types.push_back(new B);
    int var = 0;
    for(int i = 0; i<types.size(); i++){
        if(types[i].isType(A)) {types[i].run();} 
    }
    for(int i = 0; i<types.size(); i++){
        if(types[i].isType(B)) {var = lala;} 
    }
}
Run Code Online (Sandbox Code Playgroud)

我不希望B类有任何等同于run()的东西,也不希望A类具有等同于lala的东西.

我知道fortran有一个解决方法

select type ( x => var )
class is ( A )
    x.run()
end select
Run Code Online (Sandbox Code Playgroud)

但我不确定我在C++中的选择是什么.

谢谢

Gor*_*gar 5

你在找dynamic_cast.

#include <vector>
using namespace std;

class X {
public:
    int id;
    virtual ~X() = default;
};

class A : public X {
public:
    void run() {}
};

class B : public X {
public:
    int lala;
};

main(){
    vector<X *> types;
    types.push_back(new A);
    types.push_back(new B);
    int var = 0;
    for(int i = 0; i<types.size(); i++){
        if (auto ta = dynamic_cast<A *>(types[i])) {
            ta->run();
        }
    }
    for(int i = 0; i<types.size(); i++){
        if (auto tb = dynamic_cast<B *>(types[i])) {
            var = tb->lala;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

另请参阅此处的操作:https://onlinegdb.com/B1d29P5if.

我不得不修复代码中的一些其他问题.由于它们不是您问题的一部分,我不会在此澄清,但欢迎您询问是否有不明确之处.

编辑:上面的解决方案有内存泄漏,我没有解决,因为问题不需要.为了完整起见,这里是修复内存泄漏的主要功能(https://onlinegdb.com/ByeOmu9iz):

int main() {
    vector<unique_ptr<X>> types;
    types.emplace_back(new A);
    types.emplace_back(new B);
    int var = 0;
    for(int i = 0; i < types.size(); ++i) {
        if (auto ta = dynamic_cast<A *>(types[i].get())) {
            ta->run();
        }
    }
    for(int i = 0; i < types.size(); ++i) {
        if (auto tb = dynamic_cast<B *>(types[i].get())) {
            var = tb->lala;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这是一个C++ 11解决方案.

如果您正在使用更旧的编译器,则必须像原始解决方案一样继续使用普通指针,并通过调用delete向量的每个元素在最后手动释放内存.(希望你达到这一步之前没有抛出异常.)您还可以更换auto taA* taauto tbB* tb.

  • 修复泄漏不会有什么坏处. (2认同)