第三周:C++组合、继承、虚函数与多态【Boolean】
2017-02-15 14:51
239 查看
1.Composition复合
has a的关系,表示一个类是另一个类的成员变量,一个类包含另一个类
复合关系下的构造和析构
构造由内而外
Container的构造函数首先调用Component的default构造函数,然后才执行自己。
Container::Container(…):Component() {…};
析构由内而外
Container的析构函数首先执行自己,然后才调用Component的析构函数。 Container::~Container { … ~Component(); }
具体事例
构造-由内而外:B的构造函数会首先调用A的默认构造函数(编译器自己调用,如果需要传递参数,需要在初始化列表显示调用),然后在调用自己的构
析构-由外而内:B的析构函数首先执行自己的,然后才调用A的析构函数
Adapter模式
新需求所要求的所有功能在一个已有的C类中已经全部实现,但是C中功能繁多,此时可以设计一个类D对C的功能进行一次封装,仅暴露需要的结构结构,此时就非常适合Composition关系
2.Delegation委托. (Composition by Reference)
has a point
类的成员变量是另一个类的指针,
这种方法有个名词 pImpl(Pointer to IMPLementation) or Handle/Body,简单理解就是接口与实现分离
参考链接:
明智地使用Pimpl
编译防火墙——C++的Pimpl惯用法解析
典型用例
C++11中的string就是用了这种方法,方法和实际实现分离,这样就可以在两个字符串相同的时候,就使用同一块内存,当其中一个发生改变时就重新分配一块内存
class A
{
public:
A(){}
virtual ~A(){}
}
class B : public A
{
};
“`
构造与析构
构造-由内而外:B的构造函数首先调用A的默认构造函数,然后在执行自己
B::B(): A()
{
…
};
析构-由外而内:B的析构函数首先执行自己,然后才调用A的析构函数
B::~B(…)
{
…
~A();
};
注意:基类的析构函数必须是virual的,否则会出现undefined behavior
4.应用
观察者模式
组合模式Composite结构型
原型模式prototype
has a的关系,表示一个类是另一个类的成员变量,一个类包含另一个类
class A {...}; class B { public: B(){} ~B(){} private: A a; int b; };
复合关系下的构造和析构
构造由内而外
Container的构造函数首先调用Component的default构造函数,然后才执行自己。
Container::Container(…):Component() {…};
析构由内而外
Container的析构函数首先执行自己,然后才调用Component的析构函数。 Container::~Container { … ~Component(); }
具体事例
构造-由内而外:B的构造函数会首先调用A的默认构造函数(编译器自己调用,如果需要传递参数,需要在初始化列表显示调用),然后在调用自己的构
B::B(...):A() { ... }
析构-由外而内:B的析构函数首先执行自己的,然后才调用A的析构函数
B::~B(...) { ... ~A(); }
Adapter模式
新需求所要求的所有功能在一个已有的C类中已经全部实现,但是C中功能繁多,此时可以设计一个类D对C的功能进行一次封装,仅暴露需要的结构结构,此时就非常适合Composition关系
class C {...}; class D { public: void func() { c.func(); } private: C c; };
2.Delegation委托. (Composition by Reference)
has a point
类的成员变量是另一个类的指针,
class A{...}; class B { public: B(){} ~B(){} private: A *a; int b; };
这种方法有个名词 pImpl(Pointer to IMPLementation) or Handle/Body,简单理解就是接口与实现分离
参考链接:
明智地使用Pimpl
编译防火墙——C++的Pimpl惯用法解析
典型用例
C++11中的string就是用了这种方法,方法和实际实现分离,这样就可以在两个字符串相同的时候,就使用同一块内存,当其中一个发生改变时就重新分配一块内存
#include <stdio.h> #include <string> using std::string; int main(int argc, char *argv[]) { string s1("123456789"); string s2(s1); string s3("123456789"); printf("s1=%p, s2=%p, s3=%p\n", s1.c_str() , s2.c_str(), s3.c_str()); //c_str() 返回字符串的首字符地址 s1 += "00"; printf("s1=%c, s2=%c, s3=%c\n", &s1 , &s2, &s3); printf("s1=%p, s2=%p, s3=%p\n", s1.c_str() , s2.c_str(), s3.c_str()); return 0; } /* TDM-GCC 4.49.2 64-bit result: s1=0000000000B41488, s2=0000000000B41488, s3=0000000000B414B8 s1=0000000000B414E8, s2=0000000000B41488, s3=0000000000B414B8 TDM-GCC 4.49.2 32-bit result: s1=00C90E34, s2=00C90E34, s3=00C90E54 s1=00C9132C, s2=00C90E34, s3=00C90E54 */
class A
{
public:
A(){}
virtual ~A(){}
}
class B : public A
{
};
“`
构造与析构
构造-由内而外:B的构造函数首先调用A的默认构造函数,然后在执行自己
B::B(): A()
{
…
};
析构-由外而内:B的析构函数首先执行自己,然后才调用A的析构函数
B::~B(…)
{
…
~A();
};
注意:基类的析构函数必须是virual的,否则会出现undefined behavior
4.应用
观察者模式
组合模式Composite结构型
原型模式prototype
相关文章推荐
- C++继承、虚函数、纯虚函数、多态、覆盖、重载、隐藏、引用等常用概念
- C++ 06 继承与组合 (has-a is-a) 以及类大小的计算 虚基类对内存模型的影响(不考虑虚函数)
- 关于C++中私有继承后虚函数的访问权限与私有继承后多态的问题
- c++的组合/继承与多态
- c++(一) 类 对象 重载 继承 多态 构造函数 虚函数 覆盖 纯虚函数等
- 搞清楚C++继承、多态、虚函数、纯虚函数
- 简单理解C++的多态公有继承及虚函数
- C++简单学习(Part2_lecture 8)(继承、重载、多态、虚函数)
- 【转】C++的继承与多态:为什么需要虚函数
- C++ 虚函数、纯虚函数、继承、虚表、多态原理相关知识点总结
- 【继承与多态】C++:继承中的赋值兼容规则,子类的成员函数,虚函数(重写),多态
- C++封装、继承、多态(虚函数、虚指针、虚表)
- C++ 类继承(廿一)--基类、派生类、多态继承、公有继承、私有继承、虚函数、保护继承、多重继承
- C++继承-重载-多态-虚函数
- 继承和多态和虚函数——C++学习笔记二
- C++ 继承 多态 虚函数 抽象
- 【继承与多态】C++:继承中的赋值兼容规则,子类的成员函数,虚函数(重写),多态
- 《读java编程思想》 c++与java的不同(C++进阶 继承 组合 多态)
- C++继承(2) - 虚函数与运行时多态
- 博览网 c++课程 第三周 组合与继承