c++学习之路:基础知识的重构与进阶(三)
c++学习之路:封装性、继承、多态性
c++学习之路:STL初探——以思维导图形式
c++学习之路:基础知识的重构与进阶(一)
c++学习之路:基础知识的重构与进阶(二)
8.类与类之间的关系
类与类之间的关系:复合 | 委托 | 继承
Composition(复合):has-a
- 一个类以另一个类的对象作为成员函数
//设计模式:adapter
template <class T>
class deque
{
protected:
Itr<T> start;
Itr<T> finish;
T** map;
unsigned int map_size;
};
template <class T>
class quene
{
...
protected:
deque<T> C; //底层容器(类queue中有一个deque容器,一个类以另一个类的对象作为成员函数)
public:
//以下利用c的操作函数完成
bool empty() const { return c.empty(); }
...
};
tips:
- 构造由内而外(即,先调用所复合类的构造函数)
Container::Container(...) : Component() {...};
- 析构由外而内(即,先调用自己本身的析构函数)
Container::~Container(...){... ~Component() };
Delegation(委托):Composition by reference
- 以指针相连
//设计模式:Handle/Body
///handle(接口)/
class StringRep;
class String
{
public:
String();
String(const char* s);
...
~String();
...
private:
StringRep* rep; //类String和StringRap以指针相连
};
///body(实现)///
class StringRep
{
friend class String;
StringRep(const char* s);
~StringRep();
int count; //内容共享
char* rep;
};
Inheritance(继承):is-a
struct _List_node_base
{
_List_node_base* _M_next;
_List_node_base* _M_prev;
};
template<typename _Tp>
struct _List_node : public _List_node_base //父类Base:_List_node_base;子类Derived:_List_node
{
_Tp _M_data;
};
Tips:
- 继承方式:公有继承、保护继承、私有继承(细节可以参照c++学习之路:封装性、继承、多态性)
- 构造由内而外
Derived::Derived(...) : Base() { ... };
- 析构由外而内
Derived::~Derived(...) { ... ~Base() };
- 父类的析构函数必须是虚函数
继承 + 虚函数
class Shape
{
public:
virtual void draw() const=0; //纯虚函数
virtual void error(const std::string& msg); //虚函数
int objectID() const;
...
};
class Rectangle : public Shape { ... };
class Ellipse : public Shape { ... };
tips:
- 虚函数:你希望子类重新定义,且已经对它有定义;纯虚函数:你希望子类重新定义,但没有默认定义,所以一定要重写纯虚函数。
//设计模式:Template Method
CDoucment::OnFileOpen()
{
...
Serialize() //虚函数
...
}
class CMyDoc:public CDoucment //继承类CDoucment
{
virtual Serialize() { ... }; //重写父类的虚函数
};
//调用
{
CMyDoc myDoc;
...
myDoc.OnFileOpen(); //通过子类的对象调用父类的函数,遇到重写的虚函数则调用子类中的该函数
}
- 通过子类的对象调用父类的函数,遇到重写的虚函数则调用子类中的该函数
继承 + 委托
class Observer //类Observer作为父类可以派生出很多子类
{
public:
virtual void update(Subject* sub, int value) = 0; //纯虚函数
};
class Subject
{
int m_value;
vector<Observer*> m_views; //委托,指向类Oberserver的对象
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);
}
};
9. 后记
侯捷老师的《c++面向对象高级开发(上)》至此就全部结束了!这是我第一次听侯捷老师的课,非常喜欢,而且受益良多。
- 其一,他的思路超级清晰,且跟一般的书籍跟课程逻辑有很大的区别。侯老师讲课,听的人完全不会无聊,能感受到那种层层深入的感觉。
- 其二,他所有的例子都来源于源代码或者很经典的设计模式,这会很好地培养一种规范编程的能力。
- 其三,这门课适合有一点基础的朋友们一鼓作气听完,可以更好地理清c++语法的基础脉络。
- 其四,c++的规则出了名的繁杂,但正因为它繁杂所以可以做很多事,又可以运算很快。这是一门值得深究的编程语言,大家加油💪