《C++ Primer》学习记录1:C++基础

仅做个人学习《C++ Primer》的一点儿记录。

2. 变量和基本类型

int* p1, p2;		// p1: pointer, p2: int;
---
int i = 0;
decltype(i) i2=0;		// 获得i的类型;
---
vector<int> vec(10);	// vec 有10个int元素,初始为0;
vector<int> vec(10, 1);	// 10个元素,均为1;
vector<int> vec{10}; 	// = vector<int> vec={10}; 1个元素,为10;{}:初始化列表。
---
int vec[]={1,2,3,4};
int *pb = begin(vec), *pe = end(vec);	// begin/end为关键字,获得数组的起始终止的指针。
--- 
// 关于 constexpr
constexpr int func(int i){ return i+5; }
int a = func(2);		// 正确~
int i = 2; int a = func(i);		// 错误

  1. 头文件不建议包含 using 声明,避免包含时的名称冲突
  2. size_t 类型:机器相关的无符号类型,足够大,可以表示任意对象的大小;建议使用数组下标时采用
  3. constexpr 常量表达式,即函数/表达式,无需计算,在编译时即可获得结果;优秀的编译器会自动进行优化。

6. 函数

  1. 函数形参使用引用,避免拷贝;const限制避免修改
  2. constexpr函数与内联函数,建议放到头文件
  3. assert是“预处理宏”,定义在cassert中,由预处理器处理,而不是编译器;
cout << __FILE__ << __func__ << __LINE__;	// 指代当前:文件名、函数名和行数,用于debug
---
//函数指针
int (*pf) (int a, int b); 
int compareInt(int a, int b);
pf = compareInt; 	// or: pf = &compareInt;
// 调用:
bool r1 = pf(3,5); 	// or: bool r1 = (*pr)(3,5);

7. 类

  1. 定义在类内部的函数是隐式的inline函数;如果定义在外部,则不是内联
  2. 成员函数通过一个名为this的额外的隐式参数来访问调用的对象,this是一个常量指针,例如:
	total.sum(); 
	Data::sum(&total)
  1. const成员函数,在函数名后面加上const关键字,才可以让const成员变量进行调用,表示这个函数不会修改变量。
  2. return一个*this(this解引用)可以获得该函数的对象
  3. istream/ostream是IO类,不能进行拷贝,只可以进行引用来实现传参
  4. 合成的默认构造函数:当没有显示的构造函数时,编译器自行创建,变量初始化的依据:1. 首先依据变量在类内的初始值,2. 根据默认初始化
  5. struct/class:仅仅默认访问权限不同。对于struct,第一个访问说明符(public/private)之前的成员是public,class的是private
  6. 建议:对于公共代码使用私有功能函数。即在public中定义一个display,调用private中的do_display,这样的好处:1. 便于在do_display中添加debug功能;2. 便于后续在private中的do_display中进行扩充;在public中进行定义,形成内联,不会增加额外开销
  7. 类的前向声明:声明有一个类,但不在这里进行定义,是一个“不完全类型”。
  8. 类中变量名称查找顺序:1. 成员函数内;2. 类中;3. 成员函数定义之前的作用域

构造函数

  1. 构造函数的初始化和赋值不同,在有const修饰时,必须采用初始化的方式
  2. 构造函数中初始化列表的初始化顺序:按照类中的定义顺序,而不是列表的顺序;
  3. 构造函数的隐式转化:实参可以经过1步转化,变为形参,例如:
item.combine(string("123"));		// 正确。显示转为string,隐式转为Sales_Data
item.combine(Sales_Data("123"));	// 正确。隐式转为string,显示转为Sales_Data
item.combine("123");				// 错误。经过了两次转化
  1. 为避免隐式转化,构造函数增加explicit关键词,加以阻止。添加在“声明”,不能加在“定义”处。且explicit定义的构造函数,只能用于直接初始化(小括号),而不能采用赋值初始化
  2. 类的静态成员,采用static关键字,将这个静态成员与“类”而不是“实例”关联在一起,存在于任何对象之外。必须在类的外部定义与初始化所有静态成员
----
// 类中
Sales_Data() = default;	// 显示表明,我们需要编译器进行默认的构造行为。
// 如果类有了其他构造函数,不使用这一行,则这个类就没有了默认构造函数
Sales_Data() = delete;	// 显示的禁止默认构造函数
---
// 一个返回*this的成员函数实例:
Student &Student::setName(string nn){
	name = nn;		// this->name = nn;
	return *this;	// 这样便修改了Student.name的值
}
//调用:
Student std1;
std1.setName("LarryDong");	
// 要注意返回的一定是 引用&,否则只改变了临时的副本,而不能修改std1的值

小结

2020年8月4日,感觉随着C++的使用,又看懂了一些当时搞不懂的内容。例如静态成员变量,在SLAM中常用作id进行计数,也必须定义在类外。同时对:explicit, constexpr,以及 return *this 有了清楚地了解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值