简体   繁体   中英

C++ virtual function and design pattern

I have an abstract base class for Data type and two inherited class, Data1 and Data2. Data1 and Data2 have different members. I have an abstract class Proc which operates on these data. Proc has a virtual function update which takes a reference of Data as parameter. Proc1 and Proc2 both define its own implementation. However both of the implementation will use members defined in concrete class Data1 and Data2. How to make this work given the parameter is a reference of Data? For example.

class Data {};
class Data1: public Data{
    int x;
};
class Data2: public Data{
    string str;
};

class Proc{
    virtual void update(const Data&) = 0;
};

class Proc1: public Proc{
    update(const Data &d){
         // this does not work
         cout << x << endl;
    }
};

class Proc2: public Proc{
    update(const Data &d){
         // this does not work
         cout << str << endl;
    }
};

Thank you for suggestions.

Update:

Maybe my issue is it's not always a good idea to define an abstract base type Data for the sake of polymorphism which Derived classes have little in common(except conceptually). It might be easier to extend the Proc class which deals with new concrete Data type in the future?

My proc class actually serves as a container for Data, which is a map of Id and deque. As you can see, it's not a good solution to provide virtual update function inside Data. Because update is more related with Proc (calculation does based on concrete Data type though).

You need to put a pure virtual method in Data called update . Then implement it in Data1 and Data2 . One of the primary goals of object oriented programming is to keep the data and code that is related to it together :).

Using dynamic_cast should do the job.

class Proc1 : public Proc {
    void update(const Data &d) {
       Data1 const* data1Ptr = dynamic_cast<Data1 const*>(&d);
       assert(data1Ptr != NULL);
       // Now use data1Ptr
    }
};

Similarly for Proc2 .

The action that you perform depends on 2 runtime types - that's a case handled by Double dispatch mechanism. You may want to check out the Visitor pattern.

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