本系列是对C+premier笔记的补充,基于黑马C++和浙大C++。

命名空间

  • std是C++标准命名空间,引用std的方式有三种,方式三最方便。注意C中不区分命名空间,只有一个全局作用域,标识符可能发生冲突。
  • ::是作用域运算符,指明作用域
#include<iostream>
//using std:cout 方式二
using namespace std; //方式三
int main() {
	//std::cout 命名空间:: 方式一
	cout << "HelloWorld" << endl;
	return 0;
}

命名空间可以嵌套定义,但要注意,子命名空间的变量必须引到底,引当前命名空间并不会引子命名空间的变量,比如当前命名空间和子命名空间有重名变量,那就回有歧义。

namespace {
...
}
using name::varaible//使用命名空间中某个变量
using namespace;//使用命名空间中所有变量
using namespace1:: namespace2; //嵌套调用

C+对C的一些增强

  • 实用性增强 C+变量随用随定义,不需要像C得在作用域开始时定义。
  • 变量监测增强,同一个/全局作用域不能重复定义变量,但是可以嵌套定义,子作用域相当于覆盖掉全局定义的变量。
  • struct增强,定义之后创建对象new不需要struct关键词(相当于类了),struct可以有成员函数,可以继承和多态。
  • 方法必须有类型,void或者有返回值类型。
  • 加了bool,占1字节,true or false。

三目运算符增强

C+中三目运算符是变量,可以被赋值(可以作为左值),注意,如果返回值里面有常量就不行。

int a = 10;
int b = 20;
(a < b ? a : b) = 30;

const增强

1.C+const是真常量,不能通过*地址进行修改。

//2.C++ const真常量
int *p;
const int a = 10;
int* x = (int*) & a;
*x = 20;
cout << a << " " << *x; // out: 10 20

如上,a的值并没有修改,这是因为C+中const的定义被放到了符号表中,以键值对存储(在只读区,压根没有内存地址),在对a取地址的时候实际上没意义,如果强转会临时开辟一个temp变量(值和a一样)让x指向它,所以对x修改并不是对a修改。

2.指针常量和常量指针。

  • 常量指针,常量的指针,指向常量的可变指针,指针(内存地址)可以改变指向其他地址,但指针地址里的内容是常量不能变。
  • 指针常量。指向变量的不可变指针,指针本身是常量不能改变指向,地址存的内容可以变。
  • 指向常量的指针常量,指向和存的内容都不能变。
  • 常量一定要初始化。
  • 别记常指针,说是谁的都有。
//3.指针常量,常量指针
//第⼀个第⼆个⼀样 代表⼀个常整形
const int a = 10;
int const b = 10;

//第三个	常量指针(所指向的内存数据不能被修改,但是本⾝可以修改) 
const int c_1 = 0;
const int* c = &c_1; //常量指针注意初始化指向的得是常量
int const* c_2 = &c_1; //const默认优先作用左边的,左边没有作用右边的,一般写上一行这种,编译器认为是一样的

//第四个	指针常量(指针变量不能被修改,但是它所指向内存空间可以被修改)
int d_1 = 10;
int* const d = &d_1; //初始化


//第五个	指向常量的指针常量(指针和它所指向的内存空间,均不能被修改)  
const int e_1 = 10;
const int* const e = &e_1;

}

3.const和define

两者类似,但是define的替换发生在预处理阶段(预处理器纯文本替换),const发生在编译阶段(编译器提供类型检查和作用域检查)

4.const内存分配 一下情况会为const常量分配内存:

  • const常量为全局extern。
  • 使用&取常量的地址,会开辟临时内存。
  • 使用常量给常量引用初始化,C+开辟空间并将引用名作为这段空间别名。

枚举增强

C枚举本质是整形,所以枚举变量可以用整形赋值,C+中不允许偷懒,只能用枚举元素初始化枚举变量,想用整形就得强转。

//enum test {
//	AAA,
//	BBB
//};

test aa =(test)1;
test bb = BBB;

引用

C不能对变量起别名,C+可以。

int& a= b; //a是b的别名
  • 引用没有定义,类型与原类型一致(常量引用是例外),不分配内存,地址和绑定的变量相同
  • 声明必须初始化,不能改变
  • 引用可以再次引用,就是某个变量的多个别名
  • &前面有数据类型就表示引用,其余都是取址符

引用本质

引用的本质是一个指针常量,编译器隐藏了解引用和&取地址过程(定义省了&,用的时候省了

引用传参

引用可以做函数参数传递,方法有三种传参方式:

  • 值传递
  • 引用传递
  • 地址传递(指针)

引用作为函数返回值

引用可以作为函数的返回值,但不要返回局部变量的引用,避免外部再次引用局部变量而此时局部变量已经销毁出现问题(静态变量或者全局变量可以,不会被销毁)

引用作为函数的返回值时,是某个变量的别名,int等其他返回值返回是值拷贝,因此当使用引用作为函数返回值时可以做左值。

指针的引用

可以用一级指针的引用代替二级指针。

常量引用

一般用在形参,限制其只读。

	int a = 10;
	const int& b = a;
	cout << &a << " "<< &b << endl;
	a = 20;
	cout << b << endl;

上述代码说明了一件事,常量引用类型可以不匹配(指可以给常量引用绑定变量),只限定了不能通过常量引用b修改a,a变了b也会变是拦不住的。同一类型(都是int)是这样的。

	double a = 10.4;
	const int& b = a;
	const double& c = a;
	a = 20.4;
	cout << b << " " << c << endl;
	return 0;

当是真正的类型不匹配(double->int),开辟了临时变量,这时候改a,c是不会变的,其他去看Primer笔记。

浙大C++

const

alt

使用普通指针定义char数组是不允许的,"Hello World"是个常量在代码段,不能进行修改,必须用常量指针(普通指针不能指向常量),用char s[]=会先把helloworld拷贝到栈区,就是可以修改的。

const + 对象,里面的成员变量都不能修改,对应就得调用const的方法保证不被修改,同时初始化要对所有变量赋初值。

类里面的const成员一定得在构造函数里初始化。

alt

函数加const,相当于this是const,因此可以构成重载(参数列表不同)。

引用

C++有三种地方放对象,栈,堆,全局数据区,三种取对象,指针,直接变量,引用。Java是只有一个堆,所以*给省掉了,C#也有可能的,去看看。

alt

从右向左看,先碰到的是变量的类型,所以没有引用的指针(引用不是个对象),但有指针的引用。

向上造型-里氏代换原则-java的对象上转型-多态基础

子类可以替换掉父类对象使用。因为有完全相同的数据结构,指针指向是一样的(只看相同的一部分),即向上造型。注意只是,把子类看成父类,子类对象的东西都还在,不是转换。

后续内容合并到思维导图中,不在此更新了