简体   繁体   中英

C++ Overloading a Function Based on shared_ptr Derived Class

There are a lot of SO questions which are similar to this, but I couldn't find precisely what I was looking for. I'm sorry if this is a duplicate.

I have a Parent class and two derived classes which inherit from it:

class Son : public Parent { ... };
class Daughter : public Parent { ... };

I then declare two shared_ptr to the Base class, and instantiate them with a shared_ptr to each of the derived classes:

shared_ptr<Parent> son = shared_ptr<Son>(new Son());
shared_ptr<Parent> daughter = shared_ptr<Daughter>(new Daughter());

Lastly, I would like to have a class which processes shared_ptr<Parent> based on which of the derived classes it points to. Can I use function overloading to achieve this effect is the question:

class Director {
public:
    void process(shared_ptr<Son> son);
    void process(shared_ptr<Daughter> daughter);
    ...
};

So I would like to be able to write the following code:

shared_ptr<Parent> son = shared_ptr<Son>(new Son());
shared_ptr<Parent> daughter = shared_ptr<Daughter>(new Daughter());
Director director;
director.process(son);
director.process(daughter);

Right now I'm having to do (which I would like to avoid):

director.process_son(boost::shared_polymorphic_downcast<Son>(son));
director.process_daughter(boost::shared_polymorphic_downcast<Daughter>(daughter));

It isn't possible to overload like that, you would need a switch statement to achieve something similar with dispatch within one method on Director .

Maybe you should move the process() method to the Parent class (and override it in Son and Daughter ), that way you can use normal virtual function resolution to call the right one.

I am not sure if there is any better ways so i usually use Visitor pattern http://en.wikipedia.org/wiki/Visitor_pattern or similar double dispatch tricks on such need.

Your objects likely don't know the shared_ptr to themself but usually simple reference works well enough.

Ideally, the Parent would provide an interface rich enough for Director to process each child correctly, without the need to know which child it is.

class Director {
public:
    void process(shared_ptr<Parent> obj);
};

If this for some reason can't be achieved, there are many design options. As pointed out above you can have the process linked together with the child class. If that doesn't suit your needs you can, for example, isolate the process from the director:

class ProcessSon: public Process, private Son {
public:
  void SpecificProc1(shared_ptr<Parent> obj) {
    // Make this part of the process based on class Son
  }

  void SpecificProc2(shared_ptr<Parent> obj) {
    // Make this part of the process based on class Son
  }
  ...
};

Do a similar one for Daughter and send the appropriate Process together with the pointer to the class to the process method of Director .

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