类和对象初步

类和对象初步
flowwalker类和对象初步
目录
- 🚀补充知识](#补充知识)
- 🚀类的定义和使用
- 🚀访问对象的成员
- 🚀类成员的访问权限(private 隐藏机制)
- 🚀内联成员函数](#内联成员函数)
补充知识
引用&
基本定义
类型名 & 引用名=变量名,引用名相当于变量名的一个别名
定义时必须初始化成某个引用变量
只能引用变量,不能引用常量、const变量和表达式
特殊的,对于const 引用(
const 类型名 &)- 定义时仍然必须初始化
- 但是可以绑定到变量、常量、const变量或表达式(此时将延长表达式值的周期)
初始化后便一直引用该变量,不会引用其他变量
1
2
3
4int a = 10;
int b = 20;
int &ref = a; // ref is now an alias for a
ref = b; // This does NOT make ref refer to b! 仅仅只是将b的值赋给了a引用某个引用的引用也成为该原变量的别名
引用作为函数返回值
!!!注意⚠️:此时可以对返回值赋值
1 |
|
常引用
不可通过常引用修改值(修改本值可以)
与引用属于不同类型
初始化:常引用=引用 or 普通变量(正确,反之则错)1
2
3
4int n=100;
const int & r=n;
r=200; // error!
n=200; // accepted
const 关键字(避免误改)
基本内容
常量
常量指针
不可通过常量指针更改值
可以改变常量指针指向
1
2
3
4
5int r=4,rr=8;
const int * p = &r;
*p=6; // error!
r=4; // ok
p=&rr // ok可把非常量指针赋给常量指针(反之不行,因为常量指针能保证不修改非常量指针指向的那个值,反之不行,除非强制类型转换)
1
2
3
4
5
6
7
8
9const int *p1;
int *p2;
p1=p2; // ok
p2=p1; // error!
// p2 现在允许修改原本被限制的内容,这可能导致通过 p1 指向的 const 对象被意外修改,违反 const 语义
p2=(int*)p1 // ok
// 去掉了 const 限定,原本const的对象可以被p2修改,但修改的合法性取决于原对象是否真的是常量:
// - 原对象本是非常量 → 安全
// - 原对象本是常量 → 未定义行为 (正常语法下,普通指针绝不允许绑定常量)
使用常量指针、常量引用、常量对象避免修改
1
2
3
4
5// 常量指针
void PrintMy(const char*p){
strcpy(p,"this"); // error!
cout<<p; //ok
}1
2
3
4
5// 常量引用
int n;
const int & r=n;
r=5; // error!
n=3; // ok常量对象只能使用构造函数、析构函数和带const关键字的函数
1
2
3
4
5
6
7
8
9// 常量对象
class Sample(){
private:
int value;
public:
void GetValue(){}
};
const Sample obj; //常量对象
obj.GetValue(); // error!
常量方法(常量成员函数)
即在类的成员函数说明后面加 const 关键字
- 不能改非静态属性的值(常量本就不能改,静态变量可以修改)
- 不能调用同类的非常量成员函数(静态成员除外)
- 定义和声明时都应使用 const 关键字
1 | class Sample { |
常量成员函数的重载
两个函数名字、参数表均相同。但一者带有 const 关键字,另一者无,算重载
编译器将自动选择合适的
mutable 关键字
可以在 const 成员函数中修改 带mutable关键字的成员变量
1 | class CTest { |
加快速度与避免改变
为了防止生成形参导致的复制会引发复制构造函数的调用,开销较大
可以考虑将
T→T&→const T&(const 确保实参不改变)
以下是一段有关 const 函数调用说明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 class Complex{
private:
double real,imag;
mutable int access;
// 用于打破 const
public:
void setreal(double r){
real=r;
}
double getreal() const{
access++; // ok for "mutable"
//imag++; // error!
}
}
void Func(const Complex &c){
//c.real=1.0; // error!
//c.setreal(20.0); //error!
double val=c.getreal(); // ok
// const 函数内部只能调用 const 的成员函数
}比较奇葩的改变方式:该变全局c来促使const的东西也变了
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
40
41
42
43
44
45
46
47
48
class Complex {
private:
double real;
double imag;
public:
// Constructor (构造函数)
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// Non-const member function (非常成员函数)
// This can modify private members
void setReal(double r) {
real = r;
}
// Const member function (常成员函数)
// This allows read-only access for the print statement
void print() const {
std::cout << "(" << real << ", " << imag << ")" << std::endl;
}
};
// Global Instance (全局变量)
Complex global_obj(1.0, 1.0);
// Function using a const reference
void Function(const Complex & c) {
std::cout << "Value of c before global change: ";
c.print();
// Aliasing
// Even though 'c' is const, the memory it points to is NOT immutable
// if there is another non-const pointer/reference to it.
global_obj.setReal(100.0);
std::cout << "Value of c after global change: ";
c.print();
}
int main() {
// Passing the global object to the function
// Inside Function(), 'c' will be an alias for 'global_obj'
Function(global_obj);
return 0;
}
动态内存管理
谁new谁到结尾delete,一一对应,不可缺少
new 关键字
变量:
p= new T数组:
p=new T[N]
其中 T 是任意类型名,N可以是整型表达式
注意⚠️:分配后调用时编译器不会检查是否越界,应自我约束
注意⚠️:一定要用 delete 释放内存!且 delete 必须指向new出来的所有空间
1 | int *p=new int; |
函数重载
函数重载,即多个函数名字相同,然而参数个数或参数类型不相同
注意⚠️:如果出现歧义,则编译报错!
1 | int max(int a, int b) {return (a > b) ? a : b;} |
函数的缺省值
定义函数的时候可以让最右边的连续若干参数有缺省值,调用函数的时候,若不写参数则默认为缺省值
- 提高可扩展性
- 方便添加新参数与修改
注意⚠️:只能最右边开始

类的定义和使用
定义类
1 | class 类名 |
注意⚠️:类定义以分号结尾
注意⚠️:
A::说明后面的函数是类A的成员函数,而非普通函数一个类的成员函数可以互相调用
类的成员函数也可以重载,可以设定参数默认值(任何有定义的表达式皆可,如:
1
2
3int Max( int m, int n);
int a, b;
void Function2 ( int x,int y= Max(a, b), int z=a*b) {...})
定义对象
1 | // 定义对象 |
对象占用的空间
- 一般来说,一个对象占用的内存空间大小 = 其成员变量的体积之和,可采用
sizeof(类名)查看
| Data Type | Memory Size (Bytes) | Typical Range / Note |
|---|---|---|
char | 1 | Stores a single character (单个字符) |
bool | 1 | Represents true or false |
int | 4 | Standard integer (标准整数) |
long | 4 or 8 | Depends on the system (取决于系统架构) |
long long | 8 | Large integer (大整数) |
double | 8 | Double-precision floating point (双精度浮点数) |
float | 4 | 单精度浮点数 |
| 指针 | 4 or 8 | 固定不变(32位系统为4,64位系统为8) |
- 每个对象各有自己的一份存储空间,互不影响
- 成员函数内存只有一份,但可以作用于不同函数
访问对象的成员
1 | class CRectangle |
类成员的访问权限(private 隐藏机制)
class 缺省情况下为 private ,struct 默认为 public
注意⚠️:
类成员函数内部能够访问 :
- 当前对象的全部属性(变量和函数)
- ⚠️同类其他对象的全部属性
类成员函数以外的地方,只能够访问该类对象的公有成员,也不能cout私有成员(类似于被屏蔽的感觉)
设置私有成员的好处:
- 若未来成员变量的类型等属性修改后,只需要更改成员函数即可,否则得把所有直接访问成员变量的语句修改
- 避免对对象的不正确操作
内联成员函数
在每个调用点直接插入函数,增大函数体的体积,但是减少函数调用开销,加快程序速度
1 | // 以下两种方法等价 |

inline 对于编译器只是建议而非命令 编译器可能忽略内联请求(对于过长的函数) 也可能自动内联未标记为 inline 的短小函数(即使在类外部定义)








