简体   繁体   中英

How to specify while using std::vector<Base*> to store Derived*

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) 
}

I have a larger program, that's the mechanics that make me confused. Should I write virtual function for every derived class? But this is very tedious. I need to get and set some specific members, do some specific function in different child class. What is a smarter way or common way to do this? thanks!

Edit: I erased the virtual solution since OP clarified that he needs to pass different parameters.

Since you have a way to know its actual type, there is nothing wrong in just casting to it, and then using it as that type:

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;
             }
            ...
        }
    } 
}

If you're not sure if the conversion is possible, use dynamic_cast instead: it returns a clean nullptr , rather than garbage, if the cast you ask is impossible.

By the way, note that the identifier() functions in the derived classes will never be called. Either you store the id in a variable accessible from Base , and then you don't need the function in each derived class, or you have to make identifier() a virtual function.

I would try really hard to find a common signature for the subclass-specific methods and then create one virtual function in the base class that can be called without some kind of ID-function.

Sometimes this can be achieved by passing some additional information needed for the subclass-specific function to the derived class's constructor, the common method could then be called eg

virtual void doClassSpecificStuff();

that uses member variables of your derived classes.

If you truly need differing return types etc, you might not want to inherit from a common ancestor OR not store all objects in the same container. Maybe composition works better than inheritance in your context (some class has-a specific worker object instead of is-a ).

There are no :

virtual std::string Base::identifier()

In this case, when you have a Base* you cant call identifier() on it

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM