Я не думаю, что вам нужно наследование, и то, что вы воспринимаете как наследство, не правильно.При работе с несколькими классами, которые работают вместе, будь то один класс, содержащий другой или родительские дочерние отношения, всегда нужно задать себе один вопрос: отношения между этими двумя классами: «Является ли это отношение» или это «Имеет отношение?».Когда вы задаете себе этот вопрос, и на него очень легко ответить, вы должны знать, какой тип дизайна понадобится вашим классам.
Например: собака - это млекопитающее, а у собаки есть лапы.Так что, если у нас есть 3 класса здесь.Структура будет выглядеть примерно так:
class Mammal {
/* code */
};
class Dog : public Mammal {
/* code */
};
Здесь у нас есть наследство, потому что Собака - Млекопитающее, и оно унаследует все черты, которые есть у всех Млекопитающих!
Затем мы получим это:
class Paws {
/* code */
};
Итак, давайте вернемся к нашему "собачьему" классу
class Dog : public Mammal {
private:
Paws paws; // this is a member of Dog because a Dog HAS PAWS!
};
Надеюсь, это прояснит базовую структуру классов!
Теперь, чтобы оглянуться назад на вашу первоначальную проблему, вот что я сделал.Я сделал базовую структуру для представления FamilyMember, где все они имеют одинаковую общую информацию друг о друге.Я полностью абстрагировал фамилию, чтобы удалить все зависимости и проверить, совпадает ли фамилия, обновить или заменить ее и т. Д. Мой код выглядит следующим образом:
struct FamilyMember {
std::string firstName_;
unsigned int age_;
char gender_;
FamilyMember() = default;
FamilyMember(const std::string& firstName, unsigned int age, char gender) :
firstName_(firstName),
age_(age),
gender_(gender)
{}
};
class Family {
private:
std::string familyName_;
std::vector<FamilyMember> members_;
public:
Family() = default;
explicit Family(const std::string& familyName) : familyName_( familyName ) {
}
void addMember(FamilyMember& member) {
members_.push_back(member);
}
FamilyMember& getMember(unsigned int idx) {
return members_.at(idx);
}
std::vector<FamilyMember>& getFamily() {
return members_;
}
const std::string& getFamilyName() const { return familyName_; }
};
int main() {
Family Smith("Smith");
FamilyMember John("John", 32, 'M');
FamilyMember Sarah("Sarah", 29, 'F');
FamilyMember Amanda("Amanda", 19, 'F');
Smith.addMember(John);
Smith.addMember(Sarah);
Smith.addMember(Amanda);
std::cout << "Meet the " << Smith.getFamilyName() << "s:\n";
for (auto& m : Smith.getFamily()) {
std::cout << m.firstName_ << " " << Smith.getFamilyName() << " " << m.age_ << " " << m.gender_ << '\n';
}
Family Jones("Jones");
FamilyMember Tom("Tom", 44, 'M');
FamilyMember Mary("Mary", 43, 'F');
FamilyMember Mike("Mike", 21, 'M');
Jones.addMember(Tom);
Jones.addMember(Mary);
Jones.addMember(Mike);
std::cout << "Meet the " << Jones.getFamilyName() << "s:\n";
for (auto& m : Jones.getFamily() ) {
std::cout << m.firstName_ << " " << Jones.getFamilyName() << " " << m.age_ << " " << m.gender_ << '\n';
}
std::cout << "We present to you today the Union between: "
<< Jones.getMember(2).firstName_ << " " << Jones.getFamilyName() << " and "
<< Smith.getMember(2).firstName_ << " " << Smith.getFamilyName() << '\n';
Jones.addMember(Amanda);
std::cout << "We now have Mr. " << Jones.getMember(2).firstName_ << " " << Jones.getFamilyName() << " and "
<< "Mrs. " << Jones.getMember(3).firstName_ << " " << Smith.getFamilyName() << " " << Jones.getFamilyName() << '\n';
return 0;
}
Так каквы можете видеть из небольшой программы выше;у нас нет зависимости от необходимости изменять фамилию вообще.С такой структурой, когда «Аманда» выходит замуж за «Майка».Она по-прежнему принадлежит семье «Смит», но она также присоединилась к семье «Джонс».Теперь, если вы попытаетесь получить доступ к ее индивидуальным данным через структуру, нет информации о ее фамилии.Вы можете получить ее имя, возраст и пол.Если вам нужна информация о фамилии, вам нужно извлечь ее из самого класса Family, так как она никогда не меняется!