GeekBand C++面向对象高级编程(上) Thrid Week
面向对象编程(Object Oriented Progamming)
Inheritance (继承)
继承表示一种 ‘is-a' 的关系。有基类(base class) 和 派生类(derived class)。 继承分为单个继承和多重继承,同时继承的访问权限也有public,private,protected(默认是private)。
class Shape
{
public:
Shape() {}
virtual ~Shape() {}
private:
int no_;
};
class Rectangle: public Shape
{
public:
Rectangle() {}
virtual ~Rectangle() {}
private:
int x_;
int y_;
};
Rectangle 继承自 Shape,Rectangle可以访问基类的成员函数。
继承关系的构造函数是由内而外,子类的构造函数先调用基类的默认构造函数,然后才执行自己。
Rectangle::Rectangle(...): Shape() {...} // Shape() 是编译器附加的代码
析构函数是由外而内,子类的析构函数首先执行自己,然后才调用基类的析构函数。
Rectangle::~Rectangle(...) { ... ~Shape() } // ~Shape() 是编译器附加的代码
base class 的 析构函数必须写成virtual,否则在以下情况会出现部分析构的情况(表现为 undifined behavior)。
Shape* ps = new Rectangle();
delete ps; // 这种情况下如果基类的析构函数不是virtual,只能执行基类的析构函数,而子类的部分不能析构。
继承中的虚函数:
- non-virtual 函数: 不希望子类重写(override)
- virtual 函数: 希望派生类重写它,如果派生类没有重写,可以使用基类的默认定义版本
- pure-virtual 函数: 派生类一定要重新定义。 定义了纯虚函数则该类被认为为抽象类。
Composition (复合)
复合是一种表示 'has-a' 的关系。一个类中包含了另一个类的实例。
class StringRep;
class String {
public:
String();
String(const String&s)
String &operator=(const Stirng&s);
~String();
private:
StringRep rep;
};
复合方式的构造函数由内而外,Container的构造函数首先调用Component的defaul构造函数,然后才执行自己。
Container::Container(...):Component() {...};
析构的时候是由外而内,Container的析构函数首先执行自己,然后才调用Component的析构函数。
Container::~Container(...) {... ~Component() };
Delegation (委托)
委托 是一种以指针方式的复合。一个类中包含了另一个类的指针。
class StringRep;
class String {
public:
String();
String(const String&s)
String &operator=(const Stirng&s);
~String();
private:
StringRep* rep;
};
面向对象的设计模式 (Object Oriented Design)
Template Method
模版方法 是预先定义好操作的骨架,预留一些步骤的实现给子类。
C++ 中继承中的虚函数即可完成这样的功能。
CDocument::OnFileOpen()
{
...
Serialize();
...
}
class CMyDoc:public CDocumment
{
virtual Serialize() {...}
}
Observer
观察者模式,是定义一种一对多的依赖关系,当这这其中的一个改变时,所有其它依赖的对象都能自动的被通知和更新。
在C++ 中可以使用 Delegation+Inheritance 实现。
class Subject
{
int m_value;
vector m_views;
public:
void attach(Observer* obs)
{
m_views.push_back(obs);
}
void set_val(int value)
{
m_value = value;
notify();
}
void notify()
{
for(int i = 0; i < m_views.size(); ++i)
{
m_views[i]->update(this, m_value);
}
}
};
class Observer
{
public:
virtual void update(Subject* sub, int value) = 0;
};
class Observer1: public Observer
{
void update(int v)
{
...
}
};
class Observer2: public Observer
{
void update(int v)
{
...
}
};
Composite
Composite的典型例子就是文件系统。文件系统由目录和文件组成。每个目录都可以装内容。目录的内容可以是文件,也可以是目录。按照这种方式,计算机的文件系统就是以递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式Composite。
C++ 中可以通过 Delegation+Inheritance 实现
class Componet
{
int value;
public:
Componet(int val) {value = val;}
virtual void add(Component*) {}
};
class Composite:public Component
{
vector c;
public:
Composite(int val):Component(val) {}
void add(Component* elem) {
c.push_back(elem);
}
};
class Leaf:public Component
{
public:
Leaf(int val):Component(val) {}
};