复合(compsosition)是类型之间的一种关系,当某种类型的对象内含它种类型的对象,便是这种关系。
例如:
class Address{/*...*/ };//某人的住址
class PhoneNumber{/*...*/ };
class Person {
public:
//...
private:
std::string name;//合成成分物
Address address;//同上
PhoneNumber voiceNumber;//同上
PhoneNumber faxNumber;//同上
};
本例中Person对象由string,Address,PhoneNumber构成。
复合这个术语有许多同义词,包括layering(分层),containment(内含),aggregation(聚合)和embedding(内嵌)。
复合有两个意义。
复合意味has-a(有一个)或is-implemented-in-terms-of(根据某物实现出)。
当复合发生于应用域内的对象之间,表现出has-a的关系,当它发生于实现域内则表现is-implemented-in-terms-of的关系。
比较麻烦的是区分has-a和is-implemented-in-terms-of这两种对象关系。
假设你需要一个template,希望制造出一组class用来表现由不重复对象组成的set。
你的第一个直接是采用标准程序库提供的set template。
不幸的是,set的实现往往招致:每个元素耗用三个指针“的额外开销。因为set通常以平衡查找树实现而成,使它们在查找、安插、移除元素时保证拥有对数时间效率。当速度比空间重要,这是个通情达理的设计,但若你的程序是空间比速度重要呢?
那么标准程序库的set提供给你的是个错误决定下的取舍。似乎你还需写个自己的template。
实现set的方法有很多。其中一种便是在底层采用linked list。而标准程序库刚好有一个list template,于是你决定复用它。
更准确地说,你决定让你自己写的set template继承std::list。也就是让set<T>继承list<T>。
于是声明set template如下:
template<typename T>//将list应用于set,错误做法
class Set: public std::list<T>{/*...*/ };
上述代码是错误的。因为是public继承,所以应该表现is-a关系。但list可以内含重复元素,若数值3051被安插到list<int>两次,则list将内含两笔3051。但Set不可以内含重复元素,若数值3051被安插到lSet<int>两次,则Set将内含一笔3051。因此”Set是一种list“并不为真。
正确的做法是,你应当了解,Set对象可根据一个list对象实现出来:
template<typename T>//将list应用于set,正确做法
class Set{
public:
bool member(const T& item) const;
void insert(const T& item);
void remove(const T& item);
std::size_t size() const;
private:
std::list<T> rep;//用来表述Set数据
};
Set成员函数可大量倚赖list及标准程序库其他部分提供的机能来完成,所以其实现很简单,只要你熟悉以STL编写程序。
总结
1.复合的意义与public继承完全不同。文章来源:https://www.toymoban.com/news/detail-530441.html
2.在应用域,复合意味has-a。在实现域,复合意味is-implemented-in-terms-of。 文章来源地址https://www.toymoban.com/news/detail-530441.html
到了这里,关于38:通过复合塑膜出has-a或“根据某物实现出”的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!