面试题一:赋值运算符函数
1 | class CMyString |
构造函数
没有返回值
构造函数的重载
析构函数
没有传入参数、没有返回值、一个类只能有一个析构函数
先构造的对象,后析构
拷贝构造函数
根据一个类的对象,复制一个一样的对象
拷贝构造函数分为浅拷贝和深拷贝两种:
- 浅拷贝只是复制指针的地址,会导致两个指针指向同一块内存,在分别delete时就会出现重复释放
- 深拷贝则创建新内存,把值拷贝进新开的内存,指针指向新开的内存
赋值运算符函数重载
方法一:
返回值为类型的引用,函数结束前返回实例自身的引用 return *this
若返回void,则不能做连续赋值操作 a=b=c
传入的参数为常量引用
引用可以避免从形参到实参会调用一次拷贝构造函数,提高效率
const 不改变传入的实例
重新分配内存时候,必须要释放之前自己已有的空间,否则会导致内存泄漏
m_pData之前指向的内存释放
判断传入的参数和当前的实例*this是否为同一实例,即this == &str
若是同一个,不进行赋值
1 | CMyString& CMyString::operator=(const CMyString& str) |
方法二:
先释放之前的内存再开辟新空间,如果此时内存不足导致new时抛出异常,那么此时m_pData已经为空指针,原来实例的状态被修改,这样违背了异常安全性(Exception Safety)的原则
因可以先创建一个临时实例,再交换临时实例和原来的实例
1 | CMyString& CMyString::operator=(const CMyString &str) |
PS:内存泄漏—程序中己动态分配的堆内存,由于某种原因程序未释放,造成系统内存的浪费
以下是这道题涉及到的其它知识点
引用
- 引用是变量的别名,一旦把引用初始化为某个变量,就可以使用该引用名指向变量
- 引用与指针的区别:
- 不存在空引用,引用必须连接到一块合法的内存
- 一旦引用被初始化,就不能被指向到另一个对象,指针可以在任何时候指向到另一个对象
- 引用必须在创建时被初始化,指针可以在任何时间被初始化
const
1. const修饰变量
const修饰的类型为TYPE的变量value是不可变的
1 | const TYPE ValueName = value; |
2. 指针使用const
(1) 指针本身是常量不可变
char* const pContent;
(2) 指针所指向的内容是常量不可变
const char* pContent;
(3)两者都不可变
const char* const pContent;
3. 函数中使用const
(1)const修饰函数参数
a.传递过来的参数在函数内不可以改变(无意义,因为Var本身就是形参)
void function(const int Var);
b.参数指针所指内容为常量不可变
void function(const char* Var);
c.参数指针本身为常量不可变(也无意义,因为char* Var也是形参)
void function(char* const Var);
d.参数为引用,为了增加效率同时防止修改
void function(const Class& Var);
//引用参数在函数内不可以改变
void function(const TYPE& Var);
//引用参数在函数内为常量不可变
(2)const 修饰函数返回值
将const类型转化为非const类型的方法 :
const_cast < type_id > (expression)