
@Shadow
记录C/C++学习 后续学Linux 偶遇明师指导 长期写作 连更大王
目录
1.C++基础
1.1域作用限定符::
1.2函数重载
1.3临时对象问题
2.引用
2.1free会怎么样呢?
2.2引用的大小
2.类和对象
2.1类域查找
2.1.1inline相关
2.1.2空类的大小
2.1.3this的内部访问与存储区域
2.1.4this指针可能存在对象里面吗?
2.1.5this指针本质:
3. 全局函数重载与成员函数重载
3.1运算符重载的两种书写格式
4.运算符重载为全局函数与成员函数原因
4.1对称性与非对称性
4.2混合类型、类型隐式转换
5.杂项重点知识汇总
※6.类内成员的初始化导图、类默认函数的构成导图、成员函数相关知识汇总(很好地帮助框架的构建)
1.C++基础
1.1域作用限定符::
只加 : : 默认访问全局变量
多次访问 可单独展开 using shad::age;
结构体 struct shad::Node n1;
1.2函数重载
全缺省与无参函数可构成重载但错误代码。
| 可重载 | 不可重载 |
| 参数类型不同 | 仅返回值不同 |
| 参数个数不同 | 仅参数名不同 |
| 参数顺序不同 | 函数静态非静态 |
| const修饰不同 | typedef 定义别名 |
下列哪个是int Add(int x,int y);重载?
A.double Add(int x,int y);
B.double Add(double x,double y);
答案:B
1.3临时对象问题
const int& r = (a+b);
//计算式a+b返回临时对象(具有常性)取别名"r"
//"const"的存在与否与a是否只读(const)无关!
//隐式转换同样
2.引用
2.1free会怎么样呢?
了解了上一个例子试分析以下代码——ra是否也变成了野引用呢?
int* a = (int*)malloc(sizeof(int) * 10);
if (a == nullptr)
{
perror("a_malloc fail");
return -1;
}
//(int*)&ra = a; //err
int*&ra = a;
free(a);
a = nullptr;
答案:ra因a的释放其变为野引用 又因a = nullptr导致其成为空指针的引用。
2.2引用的大小
孬题: x64环境下结合引用的底层是指针这句话回答以下输出:
int main()
{
int a = 10;
int& b = a;
int* c = &a;
cout << sizeof(b);
cout << sizeof(c);
return 0;
}
答案:48
原因:虽然引用底层是指针但强调的是"别名"概念 sizeof是类型大小计算b就是别名
2.类和对象
2.1类域查找
类域影响的是编译的查找规则,下⾯程序中Init如果不指定类域Stack,那么编译器就把Init当成全
局函数,那么编译时,找不到array等成员的声明/定义在哪⾥,就会报错。指定类域Stack,就是知
道Init是成员函数,当前域找不到的array等成员,就会到类域中去查找。
2.1.1inline相关
在同一个.cpp文件中类域外定义类域内的声明函数是否要inline前缀?
答:
-
编译器会根据优化设置自行决定是否将函数内联。
-
如果函数定义在 .cpp 文件中,它默认具有外部链接属性,其他编译单元(其他 .cpp 文件)可以正常链接到这个函数。
-
如果此时加了 inline,反而可能改变其链接属性,在某些情况下可能导致链接错误(特别是如果头文件中没有该函数的定义)。
2.1.2空类的大小
若对象中没有成员变量 就称作"空类" //其默认大小为1
2.1.3this的内部访问与存储区域
在函数内可手动使用this指针进行操作 但是不能改变指向!
2.1.4this指针可能存在对象里面吗?
答案:不可能 因为空类无大小默认为1
存储于栈或寄存器中 (栈优先)
2.1.5this指针本质:
Message* p = nullptr;
p->Print();
this 指针的值,就是调用成员函数的对象(p)的地址。
3. 全局函数重载与成员函数重载
| 1. 类内((类内)友元声明+类外定义) | 可以访问 private | 全访问 | 最常用 |
| 2. 类外(普通全局) | 完全独立,需要公有接口 | 只能访问 public | 简单类 |
| 3. 类内(友元且类内定义) | 隐式内联,方便 | 全访问 | 小型函数 |
class Point {
private:
int x, y;
public:
Point(int x = 0, int y = 0) : x(x), y(y) {}
// 1. 在类内声明友元(告诉编译器这个全局函数是我的朋友)
friend Point operator+(const Point& p1, const Point& p2);
};
// 2. 在类外(同一个文件)定义全局函数
Point operator+(const Point& p1, const Point& p2)
{
return Point(p1.x + p2.x, p1.y + p2.y);
}
3.1运算符重载的两种书写格式
可重载运算符仅有一目与二目:
| 运算符 | 最常用格式 | 成员函数 | 全局函数 |
| + | d1+d2 | d1.operator+(d2); | operator+(d1,d2); |
| – | d1-d2 | d1.operator-(d2); | operator-(d1,d2); |
| ++(前置) | ++d1 | d1.operator++(); | operator++(d1); |
| ++(后置) | d1++ | d1.operator++(0); | operator++(d1,0); |
| << | d1<< | 无 | operator<<(cout,d1) |
4.运算符重载为全局函数与成员函数原因
如果你有以下疑问,那么这节可以解决你的问题: 赋值运算符为什么必须重载为成员函数?重载为全局函数会发生什么? 那为什么运算符像"<"就可以重载为全局函数呢?
4.1对称性与非对称性
非赋值运算符的重载中(如对:比较运算符 )我们发现其运算符两侧的量的级别具有一致性原则。 而赋值运算符可能导致级别不同。
class Number {
int value;
public:
Number(int v = 0) : value(v) {}
int get() const { return value; }
};
************
✅ "<" 是对称操作:左右操作数地位平等
************
bool operator<(const Number& a, const Number& b) {
return a.get() < b.get();
}
*****************
❌ "=" 是非对称操作:左操作数被修改,右操作数只读
*****************
// Number& operator=(Number& lhs, const Number& rhs); // 不允许
4.2混合类型、类型隐式转换
比较运算符适合全局类型的关键在于其支持混合类型。
class Integer {
int value;
public:
Integer(int v = 0) : value(v) {}
// 转换为int
operator int() const { return value; }
};
// ✅ 全局函数可以处理多种组合
bool operator<(const Integer& i, int n) {
return i.value < n;
}
bool operator<(int n, const Integer& i) {
return n < i.value;
}
// 如果作为成员函数,只能处理一种情况:
// class Integer {
// public:
// bool operator<(int n) const { return value < n; } // Integer < int
// // 无法处理 int < Integer 的情况(除非加转换)
// };
同样的全局函数也支持了隐式类型的转换。
由此可见赋值运算符只能定义为全局函数的规定利大于弊。
5.杂项重点知识汇总
※静态成员变量一定要在类外初始化。 ※由于静态成员在类内 所以规定访问必须指定如:Date::valuable。 ※静态成员变量不能在类内初始化因为静态成员变量不属于任何对象,不走初始化列表。
※6.类内成员的初始化导图、类默认函数的构成导图、成员函数相关知识汇总(很好地帮助框架的构建)



本文到此结束,感谢观看。 不妨留下个赞是对我最大的支持 如果觉得有回顾意义不妨点个收藏 但收藏后一定要及时看哦~

![第5章,[Win32 章节] :边框绘制函数(六)-171主机测评](https://www.171host.com/wp-content/uploads/2026/08/20260822144238-6a89b55eb002b-220x150.png)

