类和类之间的关系
-
Object Oriented Programming
-
Object Oriented Design
面向对象的思想:类与类之间产生关系
关系:
-
Inheritance
-> 继承 -
Composition
-> 复合 -
Delegation
-> 委托 ->Composition by reference
-> 两个类之间用指针相连
复合(composition)
示例代码:
#pragma once
#ifndef __ADAPTER__
#define __ADAPTER__
template<class T>
class queue
{
protected:
deque<T> c; // 底层容器,这就是复合的概念
public:
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
T front() { return c.front(); }
T back() { return c.back(); }
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_front(); }
};
#endif // !__ADAPTER__
复合的概念:
queue
这个类中有一个其他的类deque<T>
-> queue
当中全部调用deque
的方法去实现功能
adapter
适配.可能在deque
当中开放了100个功能.写一个queue
复合了deque
,但是只开放了六个接口.
复合概念下的构造函数和析构函数
-
构造由内而外
示例代码:
// Container类当中复合一个Component类
Container::Container(...) : Component() {...}; // 这是正确的写法.只是在构造这一步编译器会帮我们去做这个事情
默认调用的是无参数构造函数,需要调用其他的构造函数需要手动编写修改
-
析构由外而内
示例代码:
Container::~Container(...) {... ~Component()};
Composition by reference
A
类当中包含着B
类的指针:
#pragma once
// 防卫式声明
#ifndef __STRING__
#define __STRING__
#include <string.h>
// 头文件定义
class StringRep;
class String
{
public:
// 设计构造函数 -> 这里只是定义了函数接口.并没有实现
String(const char* cstr = 0);
String(const String& str); // 接收自己为参数,所以是拷贝构造
String& operator=(const String& str); // s2 = s1,作用的是s2,那么s2就要先自毁,自毁完了以后在创建一个和s1一样大的内存空间进行拷贝
~String(); // 析构函数 -> 当类死亡的时候(离开他的作用域)析构函数就会被调用
private:
StringRep* rep;
};
#endif // !__STRING__
StringRep
类
#pragma once
#ifndef __STRINGREP__
#define __STRINGREP__
#include "string.h"
namespace {
class StringRep
{
friend class String;
StringRep(const char* s);
~StringRep();
int count;
char* rep;
};
}
#endif // !_STRINGREP__
Inheritance(继承)
继承语法:
#pragma once
#ifndef __NODE__
#define __NODE__
struct _List_node_base
{
_List_node_base* _M_next;
_List_node_base* _M_prev;
};
template<typename _Tp>
// : public _List_node_base为继承的语法
struct _List_node : public _List_node_base
{
_Tp _M_data;
};
#endif // !__NODE__
这里的构造函数和析构函数和复合的情况一样
-
构造函数先调用父类.然后才用自己的构造函数
-
析构函数先调用自己的,然后再调用父类的构造函数