C++ 注意事项——基础

1.常量定义

宏常量 - #define 常量名 常量值
const修饰 - const 数据类型 常量名 = 初始值;
注:常量初始化后不能修改,且定义时必须初始化
注:mutable 关键字可以使常函数修改参数

const 在确定初始值时是编译器常量,当然在某些情况也有可能退化为运行时常量
constexpr 更加严格了,编译器保证 constexpr 必须是编译期常量,并且 constexpr 可修饰函数使其在编译期计算。所以 constexpr 更像是 #define

2.浮点型有效位及科学计数法

浮点型 - float double --> 小数
字节       4     8
有效位     .7   .15
科学计数法 - 3e2 = 3*10^2
            3e-2 = 3*0.1^2

3.字符串风格

C风格 - char 变量名[] = "***";
C++风格 - string 变量名 = "***"; // #include <string>

4.函数参数赋值

默认参数
语法:int func(int a, int b = 10){}
注: 默认参数由右向左连续排列
函数声明存在默认参数,实现时不能存在默认参数

占位参数
参数列表中只存在数据类型 func(int = 0)

初始化列表
类名():属性(参数),属性1(参数),属性2(参数)

5.常量指针和指针常量及引用

指针占4字节(32), 8字节(64)
常量指针 - const int *p - 值不能改变
指针常量 - int * const p - 指向不能改变
const 修饰成员变量或函数时,称常成员变量/函数
注:常成员函数可以调用普通变量和常成员变量。普遍函数不能调用常成员变量

引用
给变量起别名 == 指针常量(int * const p;)
语法: 数据类型 &别名 = 变量名
注:引用必须初始化且不可再次改变

6.内存分区规则

代码区:存放函数体的二进制代码

  1. 存放CPU执行的机器指令
  2. 区域共享
  3. 只读

全局区:全局变量和静态变量及常量
栈区:自动分配释放,函数的参数值和局部变量
堆区:程序员手动分配释放的空间

7.重载条件

条件:

  1. 同一作用域
  2. 函数名称相同
  3. 参数类型、个数、顺序不同
  4. 返回值不作为重载条件

注;

  1. 引用作为重载条件
  2. 默认参数时存在冲突

8.访问权限

权限 类内 类外 继承
public Y Y Y
protected Y N Y
private Y N N

注:struct 默认公共,class 默认私有

9.静态变量

注:共享数据、编译时分配内存、类内声明,类外初始化、类名可直接访问
静态成员函数:对象共享,静态成员函数只能访问静态成员变量

10.查看内存布局

cl /d1 reportSingleClassLayout类名 文件名

11.虚继承解决菱形基础 (virtual)

12.静态多态,动态多态(virtual)

函数重载即为静态多态
静态多态编译时绑定,动态多态运行时绑定

动态多态 - 指针vfptr

  1. 继承时子类重写父类虚函数
  2. 父类指针或引用指向子类对象(base &p = son)
    虚析构解决子类堆区释放问题,纯虚析构也需要实现但抽象类无法实例

13.文件打开方式

#include <fstream>
读 ifstream
写 ofstream

打开方式 解释
ios::in
ios::out
ios::ate 初始到文件尾
ios::app 追加
ios::trunc 存在则删除在创建
ios::binary 二进制

文件读方式:

// 1
char buf[1024] = {0};
while (ifs >> buf)

// 2
while (isf.getline(buf, sizeof(buf)))

// 3
string buf;
while (getline(ifs,buf))

// 4
char c
while ( c = ifs.get() != EOF)

二进制读写 write(buf, len) | read(ifs, len)

14.模板的使用事项

template<typename T>
template<class T>

注:

  1. 推导数据类型一致
  2. 数据类型必须确定,显示指定时可以隐式转换(
  3. 普通函数优先
  4. 类模板调用时创建
  5. 类模板分文件时内容统一放于.hpp文件中