您的位置:首页 > 编程语言 > C语言/C++

c++学习笔记

2017-09-23 16:29 148 查看
1.如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

2.如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

函数:

应该考虑传引用或者传指针,如果参数不被改动应该限制成const,

如果函数较短并且频繁被调用,该函数应该写成inline函数。

参数判断,空指针判断。

在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的次数

不可在for 循环体内修改循环变量,防止for 循环失去控制。

建议for语句的循环控制变量的取值采用“半开半闭区间”写法。for (int x=0; x<N; x++)

少用、慎用goto语句,而不是禁用。

const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,

没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应)。

有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。

参数的书写要完整,不要贪图省事只写参数的类型而省略参数名字。如果函数没有参数,则用void填充。

参数命名要恰当,顺序要合理,一般地,应将目的参数放在前面,源参数放在后面。

如果参数是指针,且仅作输入用,则应在类型前加const,以防止该指针在函数体内被意外修改。

如果输入参数以值传递的方式传递对象,则宜改用“const &”方式来传递,这样可以省去临时对象的构造和析构过程,从而提高效率。

避免函数有太多的参数,参数个数尽量控制在5个以内。

尽量不要使用类型和数目不确定的参数。C标准库函数printf是采用不确定参数的典型代表

不要将正常值和错误标志混在一起返回。正常值用输出参数获得,而错误标志用return语句返回。

在函数体的“入口处”,对参数的有效性进行检查。

内存管理:

内存分配方式有三种:

1.从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。

2.在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。

栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

3.从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。

常见的内存错误及其对策

1.内存分配未成功,却使用了它。

2.内存分配虽然成功,但是尚未初始化就引用它。

3.内存分配成功并且已经初始化,但操作越过了内存的边界。

4.忘记了释放内存,造成内存泄露。

5.释放了内存却继续使用它。

不能对数组名进行直接复制与比较,malloc为p申请一块容量为strlen(a)+1个字符的内存,

再用strcpy进行字符串复制。同理,语句if(p==a) 比较的不是内容而是地址,

应该用库函数strcmp来比较。

用运算符sizeof可以计算出数组的容量(字节数)。sizeof(a)的值是12(注意别忘了’\0’)。

指针p指向a,但是sizeof(p)的值却是4。这是因为sizeof(p)得到的是一个指针变量的字节数,

相当于sizeof(char*),而不是p所指的内存容量.

delete p 后要 p=null;不然会成为指针。

“野指针”不是NULL指针,是指向“垃圾”内存的指针

(1)指针变量没有被初始化

(2)指针p被free或者delete之后,没有置为NULL

(3)指针操作超越了变量的作用范围。

A  *p;

{

    A  a;

   p = &a;    // 注意 a 的生命期

}

p->Func();      // p是“野指针”

 malloc与free无法满足非内部数据的自动执行构造函数和析构函数

如果用new创建对象数组,那么只能使用对象的无参数构造函数

位拷贝”意味着执行b.m_data = a.m_data。这将造成三个错误:一是b.m_data原有的内存没被释放,

造成内存泄露;二是b.m_data和a.m_data指向同一块内存,a或b任何一方变动都会影响另一方;

三是在对象被析构时,m_data被释放了两次。

拷贝构造函数是在对象被创建时调用的,而赋值函数只能被已经存在了的对象调用

赋值函数步骤:1. 检查自赋值 2. 释放原有的内存资源3.分配新的内存资源,并复制内容4.返回本对象的引用

基类与派生类的析构函数应该为虚函数,不然Base * pB = new Derived;  delete pB; 只会调用基类的虚构函数

派生类的赋值函数时,注意要对基类的数据成员重新赋值

命名规范 

常量全大写、静态前面加s、函数名的每个单词首字母大写、局部变量名第一个单词外每个单词首字母大写除、不同全局变量名前面加g

封装可以使得代码模块化,继承可以扩展已存在的代码,多态的目的则是为了接口重用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: