有没有更好的方法来切换没有虚拟功能的功能?

问题描述:

我正在学习C++。我有一个基类Base及其派生类Derived。他们将push_back分成std::vector<Base*> vec。假设vec[0] == &Basevec[1] == &Derived,我可以切换功能vec[0]vec[1]没有虚拟功能。代码在这个问题的最后。有没有更好的方式没有虚拟功能?我想要纯数据类,我想添加非成员函数来修改它们以避免修改数据类的代码。非常感谢你。有没有更好的方法来切换没有虚拟功能的功能?

class TypeInterface { 
public: 
    virtual int type(void) = 0; 
    virtual ~TypeInterface() {} 
}; 

class Base : public TypeInterface { 
public: 

    static constexpr int type_ = 1; 
    virtual int type(void) { 
     return type_; 
    } 

    virtual ~Base() {} 
}; 

class Derived : public Base { 
public: 

    static constexpr int type_ = 10; 
    virtual int type(void) { 
     return type_; 
    } 

    virtual ~Derived() {}; 
}; 

void Function(Base* ptr) { 
    std::cout << "function for Base" << std::endl; 
} 

void Function(Derived* ptr) { 
    std::cout << "function for Derived" << std::endl; 
} 

void SwitchFunction(int type, void* ptr) { 
    switch (type) { 
    case 1: { 
     Base* original_type_ptr = static_cast<Base*>(ptr); 
     Function(original_type_ptr); 
     break; 
    } 
    case 10: { 
     Derived* original_type_ptr = static_cast<Derived*>(ptr); 
     Function(original_type_ptr); 
     break; 
    } 
    default: 
     std::cout << "invalid type(=" << type << ")" << std::endl; 
    } 
} 

void test_function_selecter(void) { 

    Base b; 
    Derived d; 

    std::vector<Base*> vec; 

    vec.push_back(&b); 
    vec.push_back(&d); 

    for (auto e: vec) { 
     SwitchFunction(e->type(), e); 
    } 

} 
+1

你的代码有未定义的行为。那些是一些讨厌的演员。理想情况下,当你刚刚学习C++时,你根本不应该使用指针或转换... –

+1

如何将函数存储为变量?如果它用于所有实例,则可以将其设置为静态。 std :: function myFunc = [](void){// do something} – Striker

+0

谢谢你,Kerrek SB。我试图找到你的担心,我想你可能会担心我可能会使用错误的类型和void *组合。在我的情况下,SwitchFunction(e-> type(),e)具有固定格式。所以我希望我可以避免选错组合。 – mora

你不需要“type_”或“整型(无效)”,而不是使用“typeid的”

void SwitchFunction(Base* ptr) 
{ 
    auto&& type = typeid(*ptr); 
    if (type == typeid(Base)) 
     Function(dynamic_cast<Base*>(ptr)); 
    else if (type == typeid(Derived)) 
     Function(dynamic_cast<Derived*>(ptr)); 
    else std::cout << "invalid type(=" << type.name() << ")" << std::endl; 
} 

可惜,这可能不回答你的问题正确,因为它需要“基地”有一个虚拟功能(例如析构函数,当你的类型涉及层次结构时,通常建议使用虚拟函数)

+0

谢谢Issac。恐怕我无法告诉你我的观点。重点是我想添加函数来处理数据类而不修改数据类。如果我使用虚拟类,则需要为数据类添加(并修改)虚拟功能。所以虚拟析构函数对我来说可以。再次感谢您的解决方案。但让我多问你一点。从速度表现的角度来看,你的方式还是我的方式,更好还是相同? – mora

+1

&more可能大致相同,但如果你真的关心我会建议测试它,我个人不会打扰,除非你拥有的类型数量非常大,在这种情况下,'switch'语句可能会执行'if/else if'语句(你不能使用'switch'和'typeid'),当然我的解决方案在你的对象中占用更少的空间,这可能比次要的性能差异更重要。 – Isaac