C++复习笔记2
函数重载(重定义)
是函数符号生成规则中的函数形参作为支持
函数重载就是对函数进行重定义
函数覆盖就是函数的重写
三要素
1.同名
2.不同参数
3.同一作用域
函数符号的生成规则
1.C
以函数名为生成规则
2.C++
以函数原型为为生存规则
- 返回值
- 函数名
- 函数形参(与函数重载有关)
(1)参数个数
(2)参数类型
(3)参数顺序
其他:
【不同作用域可以存在同名变量】
【所有变量类型系统都可以进行强制转换,程序可以运行但有可能导致数据丢失,系统会提示警告】
【main中不能有同名函数,否则就近原则将调用main中的该函数而不调用外面的函数】
new和malloc
/ | / | / |
---|---|---|
C | malloc[void*malloc(size_t size)] | free [void free(void*ptr)] |
C++ | new | delete |
new和malloc的区别
- new是关键字,malloc是函数
- new在自由存储区域开辟内存,malloc在堆上开辟内存
- new可以重载,malloc不能重载
- new可以调用malloc,malloc不能调用new
- 如果内存开辟失败,new抛出异常,malloc返回NULL(因为如果是空会开辟失败所以一般先判空)
- new可以开辟常量,malloc不能
- new可以以下两个函数做初始化,malloc不能
new | malloc |
---|---|
operator new(用来开辟内存) | 单纯开辟内存 |
constructor (初始化) |
const
常量是一种标识符,他的值在运行期间恒定不变。c语言用#define来定义常量(宏常量)。C++除了#define海葵科哟用const来定义常量(const常量)。
C中const与C++中的const不同
- C
- 在C中const为常变量
在编译阶段处理 常变量没有左值
- 在C中const为常变量
- C++
- 在C++中const称为常量
在编译阶段处理 把常量使用的地方替换常量初始值
- 一定要初始化
- 不允许左值(不允许在左边)
- 不允许间接访问来修改常量内存,杜绝间接访问的风险。
- 在C++中const称为常量
-
- C中const修饰的全局变量 g
- C++中const修饰的全局变量 l extern
- const的优点
C++ 语言可以用const 来定义常量,也可以用 #define 来定义常量。但是前者比后
者有更多的优点:
(1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安
全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会
产生意料不到的错误(边际效应)。
(2) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。
- 常函数
- 【规则5-2-1】在C++ 程序中只使用const 常量而不使用宏常量,即const 常量完全
取代宏常量。 - 【const数据成员无法建立在整个类中恒定的常量,应使用类中的枚举常量来实现。】
枚举常量
摘自 《高质量C++C编程指南》
有时我们希望某些常量只在类中有效。由于#define 定义的宏常量是全局的,不能达
到目的,于是想当然地觉得应该用const 修饰数据成员来实现。const 数据成员的确是存
在的,但其含义却不是我们所期望的。const 数据成员只在某个对象生存期内是常量,而
对于整个类而言却是可变的,因为类可以创建多个对象,不同的对象其const 数据成员
的值可以不同。
不能在类声明中初始化const 数据成员。以下用法是错误的,因为类的对象未被创
建时,编译器不知道SIZE 的值是什么。
class A
{…
const int SIZE = 100; // 错误,企图在类声明中初始化const 数据成员
int array[SIZE]; // 错误,未知的SIZE
};
const 数据成员的初始化只能在类构造函数的初始化表中进行,例如
class A
{…
A(int size); // 构造函数
const int SIZE ;
};
A::A(int size) : SIZE(size) // 构造函数的初始化表
{
…
}
A a(100); // 对象 a 的SIZE 值为100
A b(200); // 对象 b 的SIZE 值为200
怎样才能建立在整个类中都恒定的常量呢?别指望const 数据成员了,应该用类中
的枚举常量来实现。例如
class A
{…
enum { SIZE1 = 100, SIZE2 = 200}; // 枚举常量
int array1[SIZE1];
int array2[SIZE2];
};
枚举常量不会占用对象的存储空间,它们在编译时被全部求值。枚举常量的缺点是:
它的隐含数据类型是整数,其最大值有限,且不能表示浮点数(如PI=3.14159)。
引用
引用就是别名(引用底层以指针作为支持)
- 引用一定要初始化
- 引用不能引用不能取地址的数据
- 引用不能改变
【在语法层面没有语法可以实现改变引用】
int a=10;
int &b=a;
//&c=b;X
//c=b;X
/int c = b;X
- 引用变量只能使用引用变量所有引用的数据。
内联函数inline(本文件可见,一般写在头文件里)
编译阶段——在代码的调用点直接展开代码
inline与static修饰的函数的区别
- inline函数 在调用点直接代码展开
- static 函数符号
inline与宏的区别
- inline——编译 ——类型检查和安全检查
- 宏 ——预编译 ——无
- inline是一个更安全的宏
【注意事项】- 实现在.h文件
- 只在Release版本生效
- 是给编译器的一个建议(采不采纳建议编译器说了算)
- 基于实现,不是声明
- 递归、循环、switch不使用(??)
inline的缺点
以代码膨胀为代价 空间换时间
建议:
- 开栈的开销 > 执行的开销 建议设置为inline
- 开栈的开销 < 执行的开销 不建议设置inline
函数的默认值
- 自右向左依次赋于
- 默认值不能重复赋予
- 一般赋在声明上
C和C++的相互调用
extern “C” C++独有
- C++调用C
C++源文件里加上 extern “C” - C调用C++
C++源文件里可修改 extern “C”
C++源文件里不可修改 加中间层 .cpp - 不明确编译器
ifdef__cplusplus(系统自带宏)
namespace
名词作用域(防止名词冲突)
using namespace std; //using指示符暴露名词空间作用域下的所有符号
using std::cout;//暴露名词空间作用域下的单个符号。