最常见方式是在成员变量中声明另一类对象,需包含其头文件;指针或引用可用前向声明解耦;依赖注入推荐传const引用;静态函数调用只需类声明;友元破坏封装应慎用。

类中直接使用另一个类的对象
最常见的方式是在当前类的成员变量里声明另一个类的实例,前提是目标类已定义或前向声明。编译器需要知道该类型的完整定义才能分配内存,所以不能只靠前向声明来定义数据成员(但可以用于指针或引用)。
- 如果
A类要用B类的对象(非指针/引用),必须在A的头文件中#include "B.h",且B的定义必须已完成 - 若只用
B*或B&,可仅前向声明class B;,把#include移到A.cpp中,减少头文件依赖 - 注意循环包含:若
A.h和B.h互相#include,会编译失败;用前向声明 + 实现文件包含来解耦
通过构造函数传入另一个类的实例
适合依赖注入场景,避免硬编码创建,也便于单元测试替换实现。传值、传引用或传指针需按语义选择——尤其注意生命周期管理。
- 传
const B&最常用:避免拷贝,又防止意外修改 - 传
B*要明确所有权:谁负责析构?建议优先用std::shared_ptr<b></b>或std::unique_ptr<b></b> - 若在构造函数初始化列表中使用,确保被依赖对象的生命周期长于当前对象,否则悬空引用/指针
静态成员函数调用另一个类的静态函数
不涉及对象实例,纯工具型交互。两个类都只需声明可见,无需包含完整定义(只要函数签名已知)。
- 调用方只需看到被调用函数的声明,通常放在头文件中
-
B::helper()这样的调用,只要B类已声明且helper是public static即可 - 注意命名冲突:若两个类都有同名静态函数,需显式写明作用域,如
A::log()vsB::log()
友元类访问私有成员时的调用方式
这不是常规“调用”,而是突破封装的特殊手段,仅在强耦合且设计合理时使用。它让一个类能直接访问另一个类的私有/保护成员,但破坏了封装性,应谨慎。
立即学习“C++免费学习笔记(深入)”;
- 在
B类内声明friend class A;,则A的任何成员函数都能访问B的私有成员 - 友元关系不可继承、不可传递,且
A仍需正常包含或声明B - 更细粒度的做法是只声明特定函数为友元,比如
friend void A::process(B&);,比整个类友元更安全
实际写的时候,最容易出问题的是头文件包含顺序和循环依赖——不是语法错,而是编译不过。先理清数据流向,再决定用值、引用还是智能指针,比急着写调用逻辑更重要。


















