侯捷面向对象编程C++

1、C++书籍

语法书籍:

  • 《C++Primer》
  • 《learning Program》

提升书籍

  • 《effective C++》

标准库

  • 《The C++ standard Libaray》
2、头文件的规范
#ifndef __CLASS__//防御式申明
#define __CLASS__
class(){}
#endif
3、初始化列表

利用构造函数的初始化列表来初始化,可以提高效率,而且如果类内含有没有默认构造函数的对象,必须用这种方式来初始化数据对象。应该是在进入构造函数体之前,类内所有数据对象都已经经历了初始化阶段。

class(int a,classB b):A(a),B(b){};
4、不能重载有默认值的构造函数

违背了唯一最佳函数匹配原则

class(int r = 0):R(r){};
class(){};
//以上两个函数不能同时出现
5、函数后面加const

函数后面加const表明在这个函数里面不能改变对象的data,通常与const对象配合使用

const class a;

void read() const{return a.data;}
6、参数传递传值还是引用?

传引用比传值效率高,因为传值需要在栈内建立一个大小相同的内存,但是传引用只是一个地址,一般对于字符串,自定义的类对象传引用更加合适,同时为了防止传引用被改变原地址内容的值,可以用const修饰。

classA(const classB &b):B(b){};
7、不能返回在函数里临时创建对象的引用

不能返回在函数里临时创建对象的引用,因为临时对象函数结束就会被销毁,其地址没有意义。其他情况尽量多返回引用。

8、相同的class各个对象之间互为友元
class A {
private:
	int i;
public:
 	int f(A &a){return a.i}
}
9、代码规范总结
  • 数据private
  • 初始化列表
  • 传参多引用
  • const修饰不能少
10、返回指针对象的引用

传递者不需要知道接收者按照什么方式接受

inline complex &
    complex::operator += (const complex &c)
{return *this}

返回引用,引用返回的应该是一个左值对象,而value是一个右值对象。

函数返回值是引用(引用当左值),
当一个对象被用作右值的时候,用的是对象的值(内容),
当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。

11、操作符重载的成员函数方法和友元函数方法以及普通方法

成员函数方法多一个this指针,代表左操作数,友元函数和普通函数都没有这个this指针,而且普通函数不能访问私有变量。

C++的IO库操作符不能使用成员函数的方法重载,只能用友元函数重载(如果想访问私有变量的话)

12、设计一个函数需要思考的问题
  • 函数后面要不要加const
  • 函数参数要不要加const
  • 函数返回:要不要,能不能返回引用
13、若类内有指针,则必须自己写拷贝构造函数和拷贝赋值函数

因为默认拷贝构造函数会直接赋值指针内的地址,这样两个对象内的指针实际上指向同一块内存,非常不安全。

14、深拷贝和浅拷贝

深拷贝创建一块新内存存储内容。浅拷贝,拷贝指针地址,指向同一块内存。

15、赋值重载操作符
  • 释放之前的内存空间
  • 创建新的大小合适的内存空间
  • 将右边对象的内容拷贝到上面创建的空间中

但是如果是自我赋值,需要用一下检测避免

if(this == &args)
	return *this;
16、堆和栈

一般栈是某一个作用域的内存空间,保存参数,返回地址,以及局部变量,一个函数可以形成一个栈空间。函数结束则栈空间销毁。

堆是由系统内存分配的全局空间,可动态分配,其中的内存不会因为某个局部作用域结束而受到影响。

{
 class a;
 class *p = new class();
}
//a 和 p 都是存在于局部作用域中,也就是栈中,但是 new后产生的对象存在于堆中,所以程序结束之后 指针P被销毁,指针P中的内容是堆中的一个地址,这时候这个堆的这块地址就无法被销毁,造成了内存泄漏
17、new和delete函数干了什么事情
  • new函数

分配内存,转型,调用构造函数。

  • delete函数

调用析构函数(析构函数可能会释放对象内的动态分配的内存)

释放这个对象的动态内存

18、delete[] 与delete

当创建动态对象数组时,如果使用delete 和delete[]都能删除new分配的动态内存,但是使用delete时,只会调用一次对象的析构函数,这个时候如果对象内有指针指向其他动态内存则会发生内存泄漏,但是使用delete[],则会产生了几个对象就调用几次析构函数。

19 、类内静态函数中有静态变量
class A{
 static A& getAa();
}
A& A::getAa(){
	static A a;
	return a;
}
20、复合类关系下的构造函数和析构函数

构造由内而外,及先调用复合类(组成类)的默认构造函数,再调用类本身的构造函数,析构由外而内。

21、类委托关系(复合引用关系)

在这里插入图片描述

22、继承中基类的析构函数必须是virtual函数
23、继承中基类的函数类型
  • 非虚函数:不希望子类重写
  • 虚函数:有默认定义,希望子类重写
  • 纯虚函数:没有默认定义,子类必须重写
虚函数:   virtual fun(){};
纯虚函数: virtual fun() = 0;
非虚函数: fun(){};
24、转换函数

将一个类转换为另一个类的实例,如下图黄色表示:

在这里插入图片描述

25、explicit

明确函数的使用,编译器不能进行转换用作其他用途。如下使用explicit是为了避免二义性

在这里插入图片描述

26、函数模板 类模板 成员模板
//函数模板
template <class T>
const T& min(const T& a;const T& b)
{ return b < a?b:a}
min(r1,r2)//编译器可以进行实参推导
 //   

在这里插入图片描述
在这里插入图片描述

以上程序调用首先是创建两个子类的pair,然后用子类的pair去构造一个父类pair,由于子类型可以转化为父类型,所以构造函数正常工作。

27、模板特化,偏特化

增加T的一些特例

28、reference
//同时出现下面两个函数会引起二义性
void fun(int &a);
void fun(int a);
29、继承类 复合类的构造函数 析构函数执行次序

构造函数: 父类 复合类 自己

析构函数: 自己 复合类 父类

30、虚函数

由于子类型可以转化为父类型,所以构造函数正常工作。

27、模板特化,偏特化

增加T的一些特例

28、reference
//同时出现下面两个函数会引起二义性
void fun(int &a);
void fun(int a);
29、继承类 复合类的构造函数 析构函数执行次序

构造函数: 父类 复合类 自己

析构函数: 自己 复合类 父类

30、虚函数

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值