如何在使用std :: vector <base *>存储Derived *时指定

时间:2016-07-08 12:06:03

标签: c++

Class Base{
public:
...
    void do_Something_base();
    string identifier();
    virtual void derived1_specific() {};  // nothing relevant to Base
    virtual int derived2_specific(int) {};
};

Class Derived1:public Base {
public:
...
    string identifier();
    void derived1_specific();
};

Class Derived2:public Base {
public:
... 
    string identifier();
    int derived2_specific();
};


int main() {
   vector<Base*> owner;
   /* push back some Derived1* & Derived2* to owner */

   for (int i = 0; i < owner.size(); i++)
       if (owner->identifier() == "d1")
           owner->derived1_specific(int) 
}

我有一个更大的程序,这是让我困惑的机制。我应该为每个派生类编写虚函数吗?但这非常乏味。 我需要设置一些特定的成员,在不同的子类中做一些特定的功能。什么是更聪明的方式或常见的方式来做到这一点? 谢谢!

3 个答案:

答案 0 :(得分:1)

编辑:我删除了虚拟解决方案,因为OP澄清他需要传递不同的参数。

既然您有办法知道它的实际类型,那么只需将它转换为它,然后将其用作该类型就没有错:

Class Base{
public:
...
    void do_Something_base();
    string identifier();
};

Class Derived1:public Base {
public:
...
    string identifier();
    void TakeTwoInts(int x, int y);
};

Class Derived2:public Base {
public:
... 
    string identifier();
    const char* ReturnAString();    
};


int main() {
   vector<Base*> owner;
   /* push back some Derived1* & Derived2* to owner */

   for (int i = 0; i < owner.size(); i++)
       switch(owner[i]->identifier())
         {
           case "d1": 
            {
              Derived1* d1 = static_cast<Derived1*>(owner[i]);
              d1->TakeTwoInts(1,2);
              break;
             }
            case "d2":
             {
              Derived2* d2 = static_cast<Derived2*>(owner[i]); 
              printf("%s",d2->ReturnAString());
              break;
             }
            ...
        }
    } 
}

如果你确定转换是否可行,请改用dynamic_cast:如果投了你,它会返回一个干净的nullptr,而不是垃圾问是不可能的。

顺便提一下,请注意,派生类中的identifier()函数永远不会被调用。您可以将ID存储在可从Base访问的变量中,然后您不需要在每个派生类中使用该函数,或者您必须使identifier()成为虚函数。

答案 1 :(得分:1)

我会非常努力地找到特定于子类的方法的公共签名,然后在基类中创建一个虚拟函数,可以在没有某种ID函数的情况下调用它。

有时这可以通过将子类特定函数所需的一些附加信息传递给派生类的构造函数来实现,然后可以调用常用方法,例如。

virtual void doClassSpecificStuff();

使用派生类的成员变量。

如果您确实需要不同的返回类型等,则可能不希望从共同的祖先继承或不将所有对象存储在同一容器中。也许组合在上下文中比继承更好(某些类有一个特定的工作者对象而不是是-a )。

答案 2 :(得分:0)

没有:

virtual std::string Base::identifier()

在这种情况下,当你有一个Base *你就不能在上面调用identifier()