在真正需要使用友元的时候才使用,不必要的时候不使用友元,不要滥用友元!
吉林大学陈伟-面向对象程序设计(基于C++语言讲解)
从面向对象OOP技术的角度来看软件应用系统中的各个程序类之间一般会存在有如下的几种形式的关系:
-
关联(Association)
-
依赖(Dependency)
-
聚合(Aggregation)
-
组合(Composition)
-
泛化(Generalization)
水平方向的这种逻辑关系(关联、依赖)在实际的程序中应用最为广泛!
关联
B类里有A类的数据成员,不管是指针形式还是对象形式。创建B类对象,肯定会创建A类对象,两个类的联系性非常强!
一般都是单向的,更灵活,但是某些情况必须得是双向的,那就只能是双向的了。
/**
* LogManager maintains a separate thread that is awakened whenever the log buffer is full or whenever a timeout
* happens. When the thread is awakened, the log buffer's content is written into the disk log file.
*/
class LogManager {
public:
explicit LogManager(DiskManager *disk_manager)
: next_lsn_(0), persistent_lsn_(INVALID_LSN), disk_manager_(disk_manager) {
log_buffer_ = new char[LOG_BUFFER_SIZE];
flush_buffer_ = new char[LOG_BUFFER_SIZE];
}
~LogManager() {
delete[] log_buffer_;
delete[] flush_buffer_;
log_buffer_ = nullptr;
flush_buffer_ = nullptr;
}
// ...省略其他
private:
// ...省略其他
DiskManager *disk_manager_ __attribute__((__unused__));
};
聚合的例子:
/**
* Read log file from disk, redo and undo.
*/
class LogRecovery {
public:
LogRecovery(DiskManager *disk_manager, BufferPoolManager *buffer_pool_manager)
: disk_manager_(disk_manager), buffer_pool_manager_(buffer_pool_manager), offset_(0) {
log_buffer_ = new char[LOG_BUFFER_SIZE];
}
~LogRecovery() {
delete[] log_buffer_;
log_buffer_ = nullptr;
}
// ...省略其他
private:
DiskManager *disk_manager_ __attribute__((__unused__));
BufferPoolManager *buffer_pool_manager_ __attribute__((__unused__));
// ...省略其他
};
依赖
老鼠吃的行为委托给了苹果。
例子
注意上图中创建的是学生的指针数组!宿舍不负责学生的创建与销毁。
多个类的设计核心其实是单个类的设计。