const
const
是常量的意思,被其修饰的变量不可修改- 如果是类、结构体(的指针), 其成员也不不可以更改
- const 修饰的的是其右边的内容
常引用
- 引用可以被
const
修饰, 这样就无法通过引用修改数据了,可以称为常引用 const
必须写在 & 符号左边,才能算是常引用
const 引用的特点
- 可以指向临时数据(常量、表达式、函数返回值等)
- 可以指向不同类型的数据
- 作为函数参数时(此规则也适用于const指针)
- 可以接受
const
和 非const
实参 (非const引用,只能接受非const实参) - 可以跟非
const
引用构成重载
- 当常引用指向了不同类型的数据时,会产生临时变量,即引用指向的并不是初始化时的那个变量
初始化列表
只能用在构造函数中
1 | class Person { |
构造函数的互相调用
构造函数调用构造函数必须写到初始化列表里面
1 | struct Person { |
父类的构造函数问题
子类的构造函数会默认先调用父类的无参构造函数(析构函数后调用父类的析构函数)
如果子类的构造函数显式地调用父类有参的构造函数,就不再用默认调用父类无参的构造函数
如果父类缺少无参构造函数,子类的构造函数必须显式调用父类有参构造函数
1 | class Person { |
父类指针,子类指针
父类指针可以指向子类对象,是安全的,开发中经常用到(继承方式位public)
子类指针指向父类对象是不安全的
1 | struct Person { |
const 成员
const 成员: 被const 修饰的成员变量、非静态成员函数
const 成员变量
- 必须初始化(类内部初始化),也可以在声明的时候直接初始化赋值
- 非static 的 const 变量还可以在初始化列表中初始化
const 成员函数(非静态)
- const 关键字写在参数列表后面,函数的实现和声明必须带const
- 内部不能修改非staitc 成员变量
- 内部只能调用const 成员函数、static 成员函数
1
2
3
4
5
6
7
8
9
10
11
12
class Car {
public:
const int m_price;
static int haha;
void run() const {
cout << "run" << endl;
haha = 0;
//m_price = 0; // error
}
};
引用类型成员
引用类型成员变量必须初始化
- 在声明的时候初始化
- 通过初始化列表初始化
1
2
3
4
5
6
7
class T {
int age;
int& m_price;
public:
T(int& price) : m_price(price) {};
};对象类型的参数和返回值
- 使用对象类型作为函数的参数和返回值,可能会产生一些不必要的中间对象
匿名对象(临时对象)
没有变量名、没有被指针指向的对象,用完后马上调用析构
隐式构造 explicit
- C++中存在隐式构造的现象:在某些情况下,会隐式调用 单参数 的构造函数
- 可以通过关键字
explicit
禁止掉隐式构造1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using namespace std;
class Person {
int m_age;
public:
Person() {
cout << "Person() - " << this << endl;
}
Person(int age) : m_age(age){
cout << "Person(int) - " << this << endl;
}
Person(const Person& person) {
cout << "Person(const Person & person) - " << this << endl;
}
~Person() {
cout << "~Person()- " << this << endl;
}
void display() {
cout << "display() - age is " << this->m_age << endl;
}
};
void test1(Person person) {
}
Person test2() {
return 40;
}
int main() {
Person p1 = 20; //等价于 Person p1(20);
test1(30);
test2();
return 0;
}
友元
- 友元包括友元函数和友元类
- 如果将函数A(非成员函数)声明为类C的友元函数,那么在函数A就直接能访问类C的所有成员
- 如果将类A声明类C的友元类,那么在类A所有的成员函数内部都能访问类C对象的所有成员
1 |
|
内部类
- 如果将类A定义类C的内部,那么类A就是一个内部类(嵌套类)
- 内部类的特点
- 支持
public
、protected
、private
权限 - 成员函数可以直接访问其外部类对象的所有成员(反过来不行啊)
- 成员函数可以直接不带类名、对象名访问外部类的
static
成员 - 不会影响外部类的内存布局
- 可以在外部类内部定义,在外部类外部定义
1 |
|
- 内部类声明和实现分离
局部类
- 在一个函数内定义的类
特点:
- 作用域仅限于函数内部
- 其所有成员必须定义在类里面,不允许使用
static
变量 - 成员函数不能直接访问函数的局部变量(
static
变量除外)