C++ 我可以将派生类指向另一个基吗?(即:改变孩子的家庭)

C++ 我可以将派生类指向另一个基吗?(即:改变孩子的家庭),c++,derived-class,C++,Derived Class,我写了一些练习代码来理解类继承,但我不知道是否有办法做到我在标题中试图解释的事情 所以我想做的是让家庭和家庭成员上课。一个族可以有多个成员,但成员只能有一个族。但假设其中一个成员结婚了。因此,他们正在将他们的家庭从A家庭改为另一个B家庭。有没有办法做到这一点 #include <iostream> #include <string> class Family { std::string _familyName; public: Family();

我写了一些练习代码来理解类继承,但我不知道是否有办法做到我在标题中试图解释的事情

所以我想做的是让家庭和家庭成员上课。一个族可以有多个成员,但成员只能有一个族。但假设其中一个成员结婚了。因此,他们正在将他们的家庭从A家庭改为另一个B家庭。有没有办法做到这一点

#include <iostream>
#include <string>

class Family {
    std::string _familyName;
public:
    Family();
    void setFamilyName(std::string& str) { _familyName = str;}
    void printFamilyName() {
        std::cout << "Family name is: " << _familyName << std::endl;
    }
}

class Member : public Family {
    std::string _firstName;
public:
    Member();
    void setFirstName(std::string& str) { _firstName = str;}
    void changeFamily(Family *f) {} // What do i do here ?

}

int main(){
    Member m;
    m.setFamilyName("Smith");
    m.setFirstName("John");
    m.printFamilyName();
    Family f;
    B.setFamilyName("Williams");
    m.changeFamily(&f);
    m.printFamilyName();
    return 0;
}
多谢各位

(另一个问题是,是否有一种方法可以在不构造族零件的情况下创建成员变量,但在声明成员时将新成员变量绑定到现有的族变量?)

一个族可以有多个成员,但成员只能有一个族。但假设其中一个成员结婚了。因此,他们正在将他们的家庭从A家庭改为另一个B家庭。有没有办法做到这一点

#include <iostream>
#include <string>

class Family {
    std::string _familyName;
public:
    Family();
    void setFamilyName(std::string& str) { _familyName = str;}
    void printFamilyName() {
        std::cout << "Family name is: " << _familyName << std::endl;
    }
}

class Member : public Family {
    std::string _firstName;
public:
    Member();
    void setFirstName(std::string& str) { _firstName = str;}
    void changeFamily(Family *f) {} // What do i do here ?

}

int main(){
    Member m;
    m.setFamilyName("Smith");
    m.setFirstName("John");
    m.printFamilyName();
    Family f;
    B.setFamilyName("Williams");
    m.changeFamily(&f);
    m.printFamilyName();
    return 0;
}
您需要定义对象之间的关系,而不是对象类型。可以通过使用对象之间包含的容器关系,而不是类之间的基类派生类关系来实现这一点

struct Member;
struct Family
{
   std::vector<Member*> members;
}

struct Member
{
   Family* family;
}
struct成员;
结构族
{
std::向量成员;
}
结构成员
{
家庭*家庭;
}

我将让您了解如何定义类的成员函数,以便以健壮的方式维护对象之间的关系和对象的生命周期。

简短回答:否。继承是在编译时设置的,您不能在运行时更改它

但我不认为继承是你想要的<代码>成员继承
系列的所有成员和功能
。它并不意味着该
成员
家族
的任何特定实例之间存在关系。这反映在您的设计中-
\u familyName
是一个字符串,而不是对对象或某物的引用。但您可以引用其他对象。例如,像这样:

#include <iostream>
#include <string>
#include <vector>

class Family {
    std::string _familyName;
public:
    Family(std::string name) : _familyName(name) {};
    void printFamilyName() {
        std::cout << "Family name is: " << _familyName << std::endl;
    }
}

class Member {
    std::string _firstName;
    std::vector<Family*> families;
public:
    Member(Family *familyPtr) { addFamily(familyPtr) };
    void setFirstName(std::string& str) { _firstName = str;}
    void addFamily(Family *familyPtr) { families.push_back(familyPtr) };
    void printFamilies() { for (auto &ptr : families) { ptr->printFamilyName() } };
}

int main()
{
    Family Jackson("Jackson");
    Family Williams("Williams");
    Member John(&Jackson);
    Member Alice(&Williams);
    John.printFamilies();
    John.addFamily(&Williams);
    John.printFamilies();
    return 0;
}
class Mammal {
    /* code */
};

class Dog : public Mammal {
    /* code */
};
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;
}
#包括
#包括
#包括
阶级家庭{
std::string\u familyName;
公众:
Family(std::string name):\u familyName(name){};
void printFamilyName(){

std::cout我认为你不需要继承,你认为是继承的东西是不正确的。当处理多个同时工作的类时,无论是一个类包含另一个类还是父子关系,你总是要问自己一个问题:这两个类之间的关系是“是关系”吗当你问自己这个问题并且很容易回答时,你应该知道你的类需要什么样的设计类型

例如:狗是哺乳动物,狗有爪子。因此,如果我们在这里有3个类。结构如下:

#include <iostream>
#include <string>
#include <vector>

class Family {
    std::string _familyName;
public:
    Family(std::string name) : _familyName(name) {};
    void printFamilyName() {
        std::cout << "Family name is: " << _familyName << std::endl;
    }
}

class Member {
    std::string _firstName;
    std::vector<Family*> families;
public:
    Member(Family *familyPtr) { addFamily(familyPtr) };
    void setFirstName(std::string& str) { _firstName = str;}
    void addFamily(Family *familyPtr) { families.push_back(familyPtr) };
    void printFamilies() { for (auto &ptr : families) { ptr->printFamilyName() } };
}

int main()
{
    Family Jackson("Jackson");
    Family Williams("Williams");
    Member John(&Jackson);
    Member Alice(&Williams);
    John.printFamilies();
    John.addFamily(&Williams);
    John.printFamilies();
    return 0;
}
class Mammal {
    /* code */
};

class Dog : public Mammal {
    /* code */
};
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;
}
这里我们有遗传,因为狗是哺乳动物,会继承所有哺乳动物的所有特征

下一步我们要做的是:

class Paws {
    /* code */
};
让我们回到我们的“狗”课

我希望这能澄清类的基本结构


现在回顾一下您最初的问题,下面是我所做的。我创建了一个基本结构来表示一个家族成员,在这个家族成员中,他们彼此拥有相同的信息。我完全提取了姓氏以删除任何依赖项,并且必须检查姓氏是否相同,并更新或替换它。我的代码看起来像这样:

#include <iostream>
#include <string>
#include <vector>

class Family {
    std::string _familyName;
public:
    Family(std::string name) : _familyName(name) {};
    void printFamilyName() {
        std::cout << "Family name is: " << _familyName << std::endl;
    }
}

class Member {
    std::string _firstName;
    std::vector<Family*> families;
public:
    Member(Family *familyPtr) { addFamily(familyPtr) };
    void setFirstName(std::string& str) { _firstName = str;}
    void addFamily(Family *familyPtr) { families.push_back(familyPtr) };
    void printFamilies() { for (auto &ptr : families) { ptr->printFamilyName() } };
}

int main()
{
    Family Jackson("Jackson");
    Family Williams("Williams");
    Member John(&Jackson);
    Member Alice(&Williams);
    John.printFamilies();
    John.addFamily(&Williams);
    John.printFamilies();
    return 0;
}
class Mammal {
    /* code */
};

class Dog : public Mammal {
    /* code */
};
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;
}
struct FamilyMember{
std::string firstName;
无符号整数;
性别特征;
FamilyMember()=默认值;
FamilyMember(常量std::string&firstName、无符号整数年龄、字符性别):
名字(名字),,
年龄(年龄),,
性别(性别)
{}
};
阶级家庭{
私人:
std::字符串familyName_389;;
std::向量成员;
公众:
Family()=默认值;
显式族(const std::string和familyName):familyName(familyName){
}
无效添加成员(家庭成员和成员){
成员。推回(成员);
}
FamilyMember和getMember(未签名的整数idx){
返回成员地址(idx);
}
std::vector和getFamily(){
返回成员;
}
const std::string&getFamilyName()const{return familyName;}
};
int main(){
史密斯家族(“史密斯”);
家庭成员约翰(“约翰”,32,“M”);
家庭成员莎拉(“莎拉”,29,“F”);
家庭成员阿曼达(“阿曼达”,19,“F”);
史密斯.艾德成员(约翰);
史密斯.艾德成员(莎拉);
史密斯·阿达德成员(阿曼达);

一个家庭可以有多个成员,但成员只能有一个家庭对我来说,这听起来像是一个严重的设计缺陷,因为这与现实不符。你有一个虚假的继承权——家庭成员不是家庭。试图通过使用类似于家庭的范例来学习如何使用继承权是完全错误的。@NeilButterworth我愿意接受任何更好的学习建议。@korel我的建议是避免我们除非您绝对需要继承,否则通常需要多态性。我在您的代码中没有看到任何多态性,因此您几乎肯定不需要使用继承。使用组合。继承通常意味着is-a,在您的情况下,成员是一个不正确的族。成员应该是组合族的一部分。看起来你最终得到了循环依赖,结果是持久的、从未删除过的对象。你对shared_ptr的使用似乎不正确。@SergeyA,的确如此。感谢你指出这一点。非常感谢。现在我对继承有了更清晰的理解,我将查找注释中提到的其他概念。你应该注意这一点甚至不编译:你需要向每个
家族传递一个字符串(例如
家族Jackson(“Jackson”);
,而
成员将
家族作为指针,所以你需要使用
&
(例如
成员John(&Jackon);
)呜呼。我仍在想办法测试我的答案,他说