C++面向对象总结
# C++对C语言的加强和扩展
# const增强-C++中由const修饰的是一个真正的常量
- 在C语言中,const常量可通过指针进行修改,因为C语言中的const常量有自己的存储空间。
- C++中,会将常量放在符号表中,如果对常量取地址或者extern操作,编译器会临时开辟一个空间temp,让这个指针存放这个临时空间的地址。
// 如下定义在C++中是允许的,在C语言中出错
const int a = 1;
const int b = 2;
int array[a+b] = {0};
- const和#define的区别
- C++中的const常量类似于宏定义
const int c = 5; ≈ #define c 5 - C++中的const常量与宏定义不同
const常量是由编译器处理的,提供类型检查和作用域检查
宏定义由预处理器处理,单纯的文本替换
C语言中的const变量
C语言中const变量是只读变量,有自己的存储空间
C++中的const常量
可能分配存储空间,也可能不分配存储空间
当const常量为全局,并且需要在其它文件中使用,会分配存储空间
当使用&操作符,取const常量的地址时,会分配存储空间
当const int &a = 10; const修饰引用时,也会分配存储空间
# 类与类的关系
# 复合 (composition) 表示has-a
类中包含另一个类的对象,所占空间累加在当前对象上
template <class T, class Sequence = deque<T>>
class queue {
...
protected:
Sequence c; // 底層容器
public:
// 以下完全利用 c 的操作函數完成
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
reference front() { return c.front(); }
reference back() { return c.back(); }
// deque 是兩端可進出,queue 是末端進前端出(先進先出)
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_front(); }
};
构造由内而外,析构由外而内:构造时先调用里边对象的构造函数,然后再调用当前类的构造函数,析构时正好相反。
# 委托 (delegation) 表示composition by reference
类内含有另一个类的指针。
class StringRep;
class String
{
public:
... // 一些公有接口
private:
StringRep* rep; //类内含有类的指针
}
class StringRep{...};
复合与委托的区别
- 复合生命是一起出现的,有queue对象就有了deque对象。
- 而委托,类内含有指针,只有需要用到类指针的时候才会有指向的实现类,不同步。
# 继承(inheritance) 表示 is-a
父类和派生类被称为继承。
class _List_node_base{...}; // base class
class _Lisr_node: public _List_node_base {...} // derived class
注意事项:
- 父类的析构函数必须是virtual,否则会出现undefined behavior
- 构造由内向外,先执行父类的构造函数,然后才执行自己。
- 析构由外向内,先执行自己的析构函数,然后执行父类的构造函数。
inheritance with virtual functions(虚函数)
- non-virtual函数 : 不希望derived class重新定义(override)它。
- virtual函数 : 希望derived class重新定义(override,覆盖)它,父类中含有默认定义。
- pure virtual函数 : derived class必须重新定义。
int getID() const;
virtual void error(string& str);
virtual void draw() = 0;
继承中同名成员变量处理方法
1、当子类成员变量与父类成员变量同名时
2、子类依然从父类继承同名成员
3、在子类中通过作用域分辨符::进行同名成员区分(在派生类中使用基类的同名成员,显式地使用类名限定符)
4、同名成员存储在内存中的不同位置
虚继承virtual
1、如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中声明的名字进行访问时,可能产生二义性
2、如果在多条继承路径上有一个公共的基类,那么在继承路径的某处汇合点,这个公共基类就会在派生类的对象中产生多个基类子对象
3、要使这个公共基类在派生类中只产生一个子对象,必须对这个基类声明为虚继承,使这个基类成为虚基类。
4、虚继承声明使用关键字 virtual