备忘
1.mutable 可以消除const的局限性
class A
{
public:
void print() const;//声明为const的成员函数不能修改成员变量的值
private:
int m;
}
class A
{
public:
void print() const;//成员变量声明为mutable之后可以突破const的限制,此时该
//const函数可以修改成员变量的值
private:
mutable int m;
}
2.inline的使用方法
inline 是一种“用于实现的关键字”;而不是一种用于声明的关键字。(用于声明的关键字如extern)
所以其使用方法为:1在类中声明的时候加不加inline是无所谓的,在类外定义的时候必须加inline
2.直接在类内实现,则函数默认为inline
内联函数是以代码膨胀为代价的,仅仅省去了函数调用时的开销,从而提高函数的执行效率。
不宜使用内联的情况:1 函数体的代码太长 2 函数体中存在循环 3 构造函数和析构函数最好不要使用内联函数,因为它可能隐藏一些行为,如
偷偷地执行了基类或成员对象的构造函数和析构函数。
3.内联函数和宏定义的区别:
首先宏定义是C语言中的特色,应用较多,在C++中应用较少,同时应该尽量避免使用宏。
宏是在代码处不加任何验证的简单替代,而内联函数是讲代码直接插入到代码处。
4 必须采用列表初始化式初始化的成员变量
const int * a;//不用非得在列表初始化式中初始化
const int a;//必须
const int *const int a;//必须
int &a;//引用初始化必须在列表初始化中初始化,同时必须给其绑定一个对象,而不是简单赋值
5.C++有了malloc/free,为什么还需要new/delete?
malloc/free是C中库函数,new/delete是C++运算符。
对于非内部数据类型的对象而言,只用malloc/free无法满足动态对象的要求。
对象在创建的同时要执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数,不是运算符,
不在编译器的控制范围内,不能将执行构造函数和析构函数的任务强加给malloc/free.
所以,new/delete是可以在创建动态内存的时候同时自动调用析构函数,在销毁对象之前自动调用析构函数的,是C++中的运算符;
malloc/free是只能创建动态内存和销毁对象,是库函数。
6.关于继承的权限问题
关于private成员:如果成员在基类中是private,则只有基类和基类的友元可以访问该成员。派生类不能访问基类的private成员,也不能使自己的用户访问那些成员。
如果基类成员为public或者Protected,则派生列表中的访问标号决定该成员在派生类中的访问级别:
public 继承:基类成员保持自己的访问级别。
即 基类的public成员为派生类的public成员,基类的protected成员为派生类的protected成员。
protected继承:基类的public和protected成员在派生类中为protected成员。
private继承:基类的所有成员在派生类中为private成员。
7.关于static 成员变量和成员函数的问题
静态数据成员必须分配内存,但是类定义并不为成员函数分配内存,所以
static成员函数必须在类体外定义(可以分配内存),此时不能再有关键字static;
也不能在头文件中定义,否则容易出现多次包含头文件导致多次包含static,
所以只能放在类对应的.cpp中。
static成员变量只能在类体内声明,在类体外定义。
static const成员可以在类体内初始化,但是必须在类体外定义一次,只是定义的时候不用赋初值。
demo.h
class demo
{
private:
static int count;
static const int i=1;
}
demo.cpp
#include"demo.h"
int demo::count=0;
const int demo::i;
8 面向对象的设计原则:封装、继承、多态
封装的作用是为了隐藏细节,使得代码模块化;
继承的作用是为了实现代码重用;
多态的作用是为了实现接口重用。
而且现实是,要有效重用代码往往很难,,而真正最具有价值的重用是接口重用,因为“接口是公司最有价值的资源。设计接口比用一堆类来实现这个接口更难,而且接口
需要耗费更昂贵的人力和时间”。其实,继承作为为重用代码而存在的理由已经越来越薄弱了,因为“组合”可以很好的取代继承扩展代码现有的功能,而且组合表现的更好(至少可以防止类爆炸)。
因此笔者认为,继承存在的意义很大程度上是作为多态而非扩展现有的代码。
(程序员面试宝典)
9.重载(overload)和重写(覆盖 override)的区别