C++基础(一)
const
const关键字代表常量
- 修饰普通变量:代表该变量不可以被修改
- 修饰指针变量:1)分为指向常量的指针 2)自身是常量的指针
- 修饰引用:指向常量的引用,常用于函数形参
- 修饰成员函数:说明该成员函数不能修改成员变量
int a = 10;
int b = 20;
const int* ptr1 = &a; // 指向常量的指针
int const* ptr2 = &a; // 同上
int* const ptr3 = &a; // 常量指针
const int* const ptr4 = &a; // 指向常量的常量指针
const int& ref = a; // 常量引用
// ptr1 和 ptr2 可以改变指向,但不能通过它们修改值
ptr1 = &b;
ptr2 = &b;
//*ptr1 = 50; // 错误
//*ptr2 = 50; // 错误
// ptr3 不能改变指向,但可以通过它修改值
//*ptr3 = 50; // 正确
//ptr3 = &b; // 错误
// ptr4 既不能改变指向,也不能通过它修改值
//*ptr4 = 50; // 错误
//ptr4 = &b; // 错误
// ref 不能用于修改值,但可以改变引用其他值
//ref = 50; // 错误
define 宏定义
-
预处理器:#define 是一个预处理器指令,不是一个语句。它在编译前由预处理器处理。
-
类型无关:#define 定义的宏是类型无关的。它只是一个文本替换工具,将所有宏名称替换为指定的代码片段。
-
作用域:#define 没有作用域的概念。一旦定义,它就可以在其后的整个文件中使用,除非用 #undef 取消定义。
-
调试:使用 #define 定义的宏在调试时可能会带来困难,因为它们不是变量,无法被调试器跟踪。
const 常量
-
编译器处理:const 是一个编译器指令,由编译器在编译时处理。
-
类型安全:const 定义的常量是类型安全的。它有明确的类型,编译器会检查类型兼容性。
-
作用域:const 常量有明确的作用域。它可以是局部的,也可以是全局的,取决于常量的定义位置。
-
调试:const 常量更容易调试,因为它们是变量,可以被调试器跟踪。
static
static关键字
- static用于修饰局部变量,这样的局部变量在程序的执行期间只被初始化一次,并且它们的生命周期是整个程序的执行时间,但它们只在定义它们的函数内部可见。
#include <iostream>
void counter() {
static int count = 0; // 静态局部变量
count++;
std::cout << count << std::endl;
}
int main() {
counter(); // 输出 1
counter(); // 输出 2
counter(); // 输出 3
return 0;
}
- static用于修饰成员变量,静态成员变量属于类本身,而不是类的任何特定对象。它们由类的所有对象共享。
- 修饰成员函数,静态成员函数可以访问类的静态成员变量,但不能访问类的非静态成员变量。
- 修饰全局变量,可以将该变量的作用域限制在声明它的文件内部,使其不能被其他文件访问。
- 修饰普通函数,当 static 用于修饰全局函数时,该函数的可见性将被限制在声明它的源文件中,这意味着它不能被其他源文件访问。
this 指针
this 指针是一个特殊的指针,它在 C++ 类的非静态成员函数中使用,用于指向调用该成员函数的对象的地址。this 指针是每个对象自己的指针,用于访问对象自己的地址和成员。
this 指针被隐含地声明为: ClassName const this,这意味着不能给 this 指针赋值
在 ClassName 类的 const 成员函数中,this 指针的类型为:const ClassName const,这说明不能对 this 指针所指向的这种对象是不可改的(即不能对这种对象的数据成员进行赋值操作);this 并不是一个常规变量,而是个右值,所以不能取得 this 的地址(不能 &this)
inline内联函数
内联函数是在函数声明前加上 inline 关键字的函数。编译器会尝试将内联函数的代码直接嵌入到调用它的代码中,以减少函数调用的开销。
优势
- 减小函数调用的开销
- 相对于宏定义来说增加了类型检查
- 内联函数在运行时可调试,而宏定义不可以。
劣势 - 代码膨胀。内联是以代码膨胀(复制)为代价,消除函数调用带来的开销。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。
- 是否内联,程序员不可控。内联函数只是对编译器的建议,是否对函数内联,决定权在于编译器。
- 可能导致编译时间增加。
#include <iostream>
// 内联函数声明和定义
inline int max(int a, int b) {
return (a > b) ? a : b;
}
int main() {
int x = 5, y = 10;
// 调用内联函数
int maximum = max(x, y);
std::cout << "The maximum value is: " << maximum << std::endl;
return 0;
}
虚函数是否可以内联
虚函数可以内联,但是多态时不可以,因为内联的过程是在编译时进行的,然而多态是在程序运行时发生的。只有编译器已经知道要使用哪个虚函数的前提下才会内联
volatile
volatile 是一个关键字,在 C 和 C++ 编程中用于告诉编译器,被 volatile 修饰的变量可能会在任何时候被外部因素(例如,其他线程、硬件等)改变,因此编译器不应对这些变量进行优化。