C++中不创建新对象实现子类间对象访问的方法
问题解决方案
首先你的代码存在两个核心问题:头文件循环依赖和Child1未关联到Parent实例中的Child2对象,以下是具体修复方案:
第一步:解决头文件循环依赖
原代码中child1.h和child2.h互相#include会导致编译错误,需要用前向声明替代直接引用:
child1.h修改:
// 移除#include "child2.h",改用前向声明 class Child2; class Child1 { private: int Var1; public: // 函数声明保留,实现移至.cpp文件 int DoArithmetic(); int Increment_and_Multiply(); };
child2.h修改:
// 移除#include "Child1.h",因为Child2未用到Child1的任何成员 class Child2 { public: int Var2; };
第二步:让Child1访问Parent中的Child2对象
以下三种方案任选其一,均能实现修改同步到Parent实例的Child2对象:
方案1:给Child1添加Child2指针成员,Parent初始化时绑定
适用于仅需访问Child2的场景,耦合度较低。
- 修改
child1.h:
class Child2; class Child1 { private: int Var1; Child2* m_child2; // 存储目标Child2对象的指针 public: Child1() : m_child2(nullptr) {} // 设置Child2对象的指针 void setChild2(Child2* child2) { m_child2 = child2; } int DoArithmetic(); int Increment_and_Multiply(); };
- 修改
child1.cpp(实现函数):
#include "child1.h" #include "child2.h" int Child1::DoArithmetic() { return Increment_and_Multiply(); } int Child1::Increment_and_Multiply() { if (!m_child2) return 0; // 空指针防护 m_child2->Var2++; return m_child2->Var2 * Var1; }
- 修改
Parent类构造函数,绑定Child2对象:
#include "child1.h" #include "child2.h" class Parent { public: Child1 Child1_obj; Child2 Child2_obj; Parent() { // 将自身的Child2_obj地址传给Child1_obj Child1_obj.setChild2(&Child2_obj); } void setVar2_Value(int v2) { Child2_obj.Var2 = v2; } };
方案2:让Child1持有Parent指针,通过Parent访问Child2
适用于需要访问Parent其他成员的场景,扩展性更强。
- 修改
child1.h:
class Parent; // 前向声明Parent class Child1 { private: int Var1; Parent* m_parent; public: Child1() : m_parent(nullptr) {} void setParent(Parent* parent) { m_parent = parent; } int DoArithmetic(); int Increment_and_Multiply(); };
- 修改
child1.cpp:
#include "child1.h" #include "parent.h" int Child1::DoArithmetic() { return Increment_and_Multiply(); } int Child1::Increment_and_Multiply() { if (!m_parent) return 0; m_parent->Child2_obj.Var2++; return m_parent->Child2_obj.Var2 * Var1; }
- 修改
Parent构造函数:
#include "child1.h" #include "child2.h" class Parent { public: Child1 Child1_obj; Child2 Child2_obj; Parent() { Child1_obj.setParent(this); // 传入自身指针 } void setVar2_Value(int v2) { Child2_obj.Var2 = v2; } };
方案3:调用函数时传入Child2引用
适用于临时访问的场景,耦合度最低,但每次调用都需要传参。
- 修改
child1.h:
class Child2; class Child1 { private: int Var1; public: // 新增Child2引用参数 int DoArithmetic(Child2& child2); int Increment_and_Multiply(Child2& child2); };
- 修改
child1.cpp:
#include "child1.h" #include "child2.h" int Child1::DoArithmetic(Child2& child2) { return Increment_and_Multiply(child2); } int Child1::Increment_and_Multiply(Child2& child2) { child2.Var2++; return child2.Var2 * Var1; }
- 修改
main.cpp调用方式:
#include "parent.h" int main() { Parent P1; P1.setVar2_Value(5); // 传入Parent实例的Child2_obj引用 int res = P1.Child1_obj.DoArithmetic(P1.Child2_obj); // 此时P1.Child2_obj.Var2已变为6 }
内容的提问来源于stack exchange,提问作者No Man
相关产品推荐
相关产品推荐

