简体   繁体   中英

c++ design (multiple inheritance vs. listing relevant data)

I have

class Skill
{
public :
  virtual void printSkill();
//....
}

class Person : public Skill
{


//...
}

In previous design Person could have one skill per person and I could print it

Person p;
p.printSkill();

Now we want to add multiple skill and display them. I changed:

class Person
{
private:
vector<Skill*> m_skills;
pubcic:
void addSkill(Skill *s) { m_skills.push_back(s);}
void printSkills() const { 
  for auto it = m_skills.begin(); it != m_skills.end(); ++it)
  {
      it->printSkill();
  }
}
}
class Skill1 : public Skill
{
   void printSkill() ;
}

class Skill2 : public Skill
{
   void printSkill() ;
}

Person p;
Skill1 s1;
Skill2 s2;
p.addSkill(&s1);
p.addSkill(&s2);

This should work But I dont like this. may be I can solve this without addSkill method? Using MultipleInheitance?

What's best depends on a large number of factors.

With your vector<Skill*> version:

  • The same Skill -derived object may be added to multiple Person objects, which might be memory efficient and desirable, or inappropriate (eg if the Skills objects had to have Person -specific data members, such as the extent of skill, eg a bench-press skill might want a number of kgs specific to the Person )
  • There's no inherent management of the lifetime of the Skills -derived objects, which must never-the-less outlive any use of them via the pointers to them you're storing in Person objects, or you'll get undefined behaviour . This may be fine: perhaps you can create some set number of skills once in the program lifetime, and not need to destruct them until after all the Person objects' lifetimes. At other times, the calling code will have take extra responsibility and care.

Other possible approaches include:

Having Person store a vector<unique_ptr<Skill>> , and have client code hand over ownership to the skills objects it adds: addSkill(std::make_unique<SomeSkill>(constructor, args, la, de, da);

You could also have a using SomeSkill = std::variant<Skill1, Skill2, Skill3>; and have Person store a std::vector<SomeSkill> . This achieves something similar to the last, but using a buffer inside the variant big enough to store the largest Skill -derived object, instead of storing pointers off to dynamically allocated Skill objects.

You could use multiple inheritance, but then you'd have multiple base classes providing a same-named function, and to call a specific one you have to disambiguate that at the time. If you want to be able to easily declare Person s with different skills, and still have a printSkills function that automatically discovers and prints the individual skills from the multiple bases, that's possible using variadic templates and parameter packs, but judging from the question - respectfully - you're not ready to go down that route.

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