简体   繁体   中英

How shall I use derived classes with vectors and shared pointers?

I am not familiar with the concept of inheritance, and I am struggling to find a solution to the following problem.

I have 2 classes, Head and Hand. I use instances of these classes mostly as elements of a vector. The two classes have methods in common and methods peculiar only to them.

Moreover, I deal with shared pointers of the object.

I thought the best way to implement it was to create a class BodyPart, like this

class BodyPart
{
  public:
  typedef boost::shared_ptr<BodyPart> pointer;

  private:
  int commonMember1;
  double commonMember2;

  public:
  int commonMethod1();
  int CommonMethod2();
}

and the two derived classes like this

class Hand : public BodyPart
{
  public:
  typedef boost::shared_ptr<Hand> pointer;

  private:
  int numFingers;

  public:
  int getNumFingers();
  void printInfo();
}

Finally, I wanted to declare a vector of BodyPart elements:

std::vector<BodyPart::pointer> cBodyParts;

containing either Hand or Head elements, and call my methods on the vector elements when I need.

But this approach doesn't seem to work very well. Apparently, when I try to get an element of the vector, the compiler complains that it cannot convert from a BodyPart shared pointer to a Hand shared pointer. Moreover, if the vector is declared like above, I cannot call methods specific to the derived classes (like getNumFinger() ) on its element, even if the actually are from that class.

Is there a proper way to deal with this? Or is my approach completely wrong? Thanks in advance!

Your approach is correct, but so is the compiler. It's good that you have a vector of shared pointers to the base class, but you'll need to cast to the actual type to get specific functionality.

The typedef boost::shared_ptr<Hand> pointer; is useless though, you only need the typedef in the base class. You won't be casting between smart pointers. I'd rename the base class typedef to

typedef boost::shared_ptr<BodyPart> BodyPartPtr;

though.

Good point by Alan in the comments: you should make the base class's destructor virtual to prevent UB, since you'll be deleting (indirectly) pointers to derived types through a pointer to a base type.

Your approach is right (though you don't really need the typedef ), you just need to use boost::static_pointer_cast ( Doc here ) to convert from shared_ptr<BodyPart> to shared_ptr<Hand> when you need it.

You may also have a look at enable_shared_from_this at some point in your learning.

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