目录
前言
一、const关键字
1、const修饰类的成员变量
2、const修饰类的成员函数
3、const修饰类的对象
二、static关键字
1、static修饰类中的成员变量
1. 共享性
2. 初始化
3. 访问权限
4. 内存分配
5. 不依赖于对象
2、static修饰类中的成员函数
三、this关键字
返回当前对象的指针
前言
前面我们说到了C++中的类创建,其中类包括了函数,变量,以及构造函数,但是和C语言当中一样,我们对变量和函数有const和static修饰,在C语言当中我们用const修饰变量表示不可修改的变量,那么在C++中是不是也是这样呢?明确告诉大家,有共同点也有不同点,大多是不同的
一、const关键字
1、const修饰类的成员变量
当我们用const修饰类的成员变量时,这个变量在使用时和其他没有被修饰的变量有区别,即这个成员变量不能被修改,即在创建后不能被进行赋值操作。只能进行初始化。
对于const 修饰的成员变量,必须进行初始化,在创建对象时,就必须要进行初始化赋值
在类的构造函数定义的()后 添加 : 成员变量(值) , 类的初始化列表可以对成员进行初始化;
如果你要在普通函数中修改,那么是不行的,因为在我们创建对象的时候,成员变量就已经进行创建了,这时候在普通函数当中进行你所谓的“初始化”,不过是对成员变量进行赋值操作罢了。
2、const修饰类的成员函数
表示类的成员函数中,函数中没有任何的修改变量操作,只有访问变量
怎么理解呢,假如你在类的成员函数中使用了const修饰这个函数,那么你就不能在这个函数当中有任何的赋值操作,即不能在这个函数当中将某个值更改,但是能进行值的访问,
下面是某个类的成员函数声明,如果现在在getid()这个函数后面使用const修饰,那么在定义这个函数的时候,函数当中不能有更改值的操作,只能进行访问变量的功能
当然,这里使用const修饰函数写在函数后面,在声明的时候写,在定义的时候不用写const
这里我们说
声明函数是指:在头文件中声明某个函数,后面要使用时在调用头文件
定义函数是指:在.cpp文件中定义的函数功能,具体哪个函数实现什么功能就写你想要实现的功能
3、const修饰类的对象
const修饰对象时,表示整个对象不能进行修改,不能执行修改操作
被修饰的对象,只能调用const成员函数,不能调用普通成员函数
怎么样理解呢,就是说当我们在用const修饰一个对象后,这个对象里面的所有东西都不能进行修改,相当于固定不动的东西,而且被修饰的对象也不能调用普通函数,就只能调用const修饰的成员函数,和const修饰的成员变量,我们知道const修饰的成员函数只能进行成员的访问,不能进行赋值操作,那么其实对于被const修饰的对象而言,使用起来有很多限制条件,在使用时务必小心;
看代码解释:
class MyClass {
public:
void myConstFunc() const; // const成员函数
void myNormalFunc(); // 普通成员函数
};
void MyClass::myConstFunc() const {
// 不能修改成员变量
}
void MyClass::myNormalFunc() {
// 可能修改成员变量
}
void example() {
const MyClass obj;
obj.myConstFunc(); // 可以调用
// obj.myNormalFunc(); // 编译错误,不能调用
}
class MyClass {
public:
int getValue() const { return value; } // const成员函数
void setValue(int val) { value = val; } // 普通成员函数
private:
int value;
};
void example() {
const MyClass obj;
int val = obj.getValue(); // 可以调用,因为getValue是const成员函数
// obj.setValue(10); // 编译错误,不能调用,因为setValue不是const成员函数
}
二、static关键字
1、static修饰类中的成员变量
static修饰成员变量,表示成员变量不再是属于单个对象,而是属于整个类,每个类对象在访问时,都是访问同一个共有成员,整个类的所有对象只有同一个 static成员变量
其实这个有点像我们将一个静态局部变量变成一个全局变量,但是在C语言中是不能实现的,在c++中我们将其称为共享性
1. 共享性
static
成员变量属于类本身,而不是类的任何特定实例。换句话说,所有对象共享同一个static
成员变量。你可以通过类名来访问它,也可以通过类的实例访问它,但通常推荐使用类名来访问
class MyClass {
public:
static int staticVar; // 声明静态成员变量
void printStaticVar() {
std::cout << "Static Var: " << staticVar << std::endl;
}
};
// 静态成员变量必须在类外定义
int MyClass::staticVar = 0; // 定义并初始化静态成员变量
int main() {
MyClass obj1;
MyClass obj2;
obj1.staticVar = 10; // 通过对象访问
obj2.printStaticVar(); // 输出: Static Var: 10
MyClass::staticVar = 20; // 通过类名访问
obj1.printStaticVar(); // 输出: Static Var: 20
return 0;
}
2. 初始化
static
成员变量必须在类外进行定义和初始化,通常在源文件(.cpp
文件)中完成。类内的声明只是告诉编译器该成员变量存在,但不提供存储空间。初始化仅需一次,因此只需在一个地方进行。
3. 访问权限
static
成员变量的访问权限(public
、private
、protected
)与普通成员变量一样。它可以被类的成员函数、友元函数或通过对象/类名进行访问,具体取决于它的访问控制级别。
4. 内存分配
static
成员变量的内存分配在程序的全局/静态存储区域中,而不是在每个对象的内存中。这使得它们对于所有对象是共享的。
5. 不依赖于对象
static
成员变量在对象创建之前就已存在,因此它不依赖于对象的生命周期。它的值在程序运行期间保持不变,直到被修改。
2、static修饰类中的成员函数
静态成员函数也只能访问static
成员变量,不能访问非静态成员变量或成员函数。这是因为静态成员函数没有this
指针,它们不与具体的对象实例关联。
static修饰成员,让静态成员函数属于整个类,访问 static 成员变量,不能访问普通成员,可以通过类名访问,注意,这里用static修饰的成员函数只能访问static修饰的成员变量,不能访问普通变量,否则报错
class MyClass {
public:
//静态成员函数
static void staticFunc() {
std::cout << "Static Var: " << staticVar << std::endl; // 访问静态成员变量
}
private:
static int staticVar; // 静态成员变量
};
// 定义静态成员变量
int MyClass::staticVar = 0;
int main() {
MyClass::staticVar = 100;
MyClass::staticFunc(); // 输出: Static Var: 100
return 0;
}
三、this关键字
对于类的成员函数,为了访问在调用成员函数时确定对象,编译器会为类的每个成员函数(除了static函数)都会隐式的添加一个 类* this 作为函数参数。通过对象调用函数时,会由编译器传递对象的地址 给这个this指针。this指针存储的是调用成员函数的对象的地址,防止访问错误(访问其他的对象)
对于this指针可以将其理解为当成员函数需要明确访问当前对象的成员变量时,this
指针可以用来区分局部变量和成员变量。只能在非静态成员函数中使用
class MyClass {
private:
int value;
public:
MyClass(int value) {
// 使用 this 指针区分成员变量和参数
this->value = value;
}
void printValue() {
std::cout << "Value: " << this->value << std::endl;
}
};
返回当前对象的指针
this
指针可以用于在成员函数中返回当前对象,便于链式调用(即多个操作连接在一起,连续调用)。
class MyClass {
private:
int value;
public:
MyClass& setValue(int value) {
this->value = value;
return *this; // 返回当前对象的引用
}
void printValue() const {
std::cout << "Value: " << value << std::endl;
}
};
int main() {
MyClass obj;
obj.setValue(10).setValue(20).printValue(); // 链式调用
return 0;
}