如何实现同属同一对象的两个子对象间的方法调用?
优化类间方法访问的面向对象实现方案
问题背景
你定义了类c,其成员包含类a和类b的实例;需求是让b的对象能访问c中a对象的方法。当前实现是在b内部封装a的add方法,同时让b持有自己的a实例——这种方式存在冗余(c和b各持有一个a实例,数据独立),且不符合单一职责原则。
以下是你的原始代码:
#include <iostream> class a { public: a(){i = 1; j = 2;} int add() { return i + j; } private: int i; int j; }; class b { public: b() {} int add() { return k + l; } int adda() { return A.add(); } private: int k; int l; a A; }; class c { public: int add() { return A.add() + B.add(); } int addainb() { return B.adda(); } private: a A; b B; }; int main() { c C; int res = C.addainb(); std::cout << res << std::endl; return 0; }
更优的OOP实现方案
方案1:依赖注入(传递引用/指针)
核心思路:让b不再持有独立的a实例,而是通过构造函数或 setter 接收c中a实例的引用,直接复用同一个a对象。这种方式符合依赖倒置原则,减少冗余,同时保持封装性。
修改后的代码示例:
#include <iostream> class a { public: a(){i = 1; j = 2;} int add() { return i + j; } private: int i; int j; }; class b { public: // 构造函数注入a的引用 b(a& a_inst) : A(a_inst) {} int add() { return k + l; } int adda() { return A.add(); } private: int k; int l; a& A; // 存储引用而非独立实例 }; class c { public: // 初始化b时传入自身的a实例引用 c() : B(A) {} int add() { return A.add() + B.add(); } int addainb() { return B.adda(); } private: a A; b B; }; int main() { c C; int res = C.addainb(); std::cout << res << std::endl; return 0; }
优点:
b和c共享同一个a实例,避免数据不一致b无需管理a的生命周期,由c负责- 降低耦合度,
b只依赖a的抽象接口
方案2:通过类c转发调用
核心思路:如果b不需要直接感知a的存在,可以让c作为中介,把a的方法调用转发给b。这种方式完全隔离b和a的依赖,适合低耦合场景。
修改后的代码示例:
#include <iostream> class a { public: a(){i = 1; j = 2;} int add() { return i + j; } private: int i; int j; }; class b { public: b() {} int add() { return k + l; } // 直接接收外部传入的计算结果,无需知道a的存在 int use_add_result(int add_val) { return add_val; } private: int k; int l; }; class c { public: int add() { return A.add() + B.add(); } int addainb() { return B.use_add_result(A.add()); } private: a A; b B; }; int main() { c C; int res = C.addainb(); std::cout << res << std::endl; return 0; }
优点:
b和a完全解耦,各自职责更单一- 代码扩展性更好,修改
a的实现不影响b
缺点:如果需要调用a的多个方法,c需要编写大量转发函数,会增加代码量。
方案3:友元类(谨慎使用)
核心思路:通过声明友元,让b直接访问c中的a实例。这种方式实现简单,但会破坏封装性,仅适合高度耦合的特殊场景。
修改后的代码示例:
#include <iostream> class a { public: a(){i = 1; j = 2;} int add() { return i + j; } private: int i; int j; }; class c; // 前向声明 class b { public: b(c& c_inst) : C(c_inst) {} int add() { return k + l; } int adda(); private: int k; int l; c& C; }; class c { public: c() : B(*this) {} int add() { return A.add() + B.add(); } int addainb() { return B.adda(); } private: a A; b B; friend class b; // 声明b为友元,允许其访问私有成员 }; // 实现b的adda方法 int b::adda() { return C.A.add(); } int main() { c C; int res = C.addainb(); std::cout << res << std::endl; return 0; }
优点:实现简单,无需额外的引用传递逻辑
缺点:破坏了类的封装性,增加了代码维护难度,不符合OOP的封装原则
方案推荐
优先选择依赖注入方案,它在封装性、耦合度和代码可维护性之间达到了最佳平衡,是面向对象编程中处理依赖关系的标准做法。如果需要极致的解耦,可以考虑通过c转发调用的方案;友元类仅作为特殊场景下的备选。
内容的提问来源于stack exchange,提问作者A.Agan
相关产品推荐
相关产品推荐

