文章目录
1. this指针
1.1 this指针的概念
1.c++规定,this指针是隐含在对象成员函数内的一种指针。当一个对象被创建后,它的每一个成员函数都含有一个系统自动生成的隐含指针this,用以保存这个对象的地址。
2.this指针是C++实现封装的一种机制,它将对象和该对象调用的成员函数连接在一起,在外部看来,每一个对象都拥有自己的函数成员。一般情况下,并不写this,而是让系统进行默认设置。
3.本质:this指针的本质是一个常量指针 Type* const pointer
; 它储存了调用它的对象的地址,不可被修改
3.注意:
(1)this指针永远指向当前对象。
(2)静态成员函数内部没有this指针,静态成员函数不能操作非静态成员变量。
//this:是指向当前对象的指针
//当前对象:谁调用这个函数,this指向谁;
//大多数情况下,this可以不写;
class Person
{
public:
//构造函数
Person():_age(0){}
Person(int age):_age(age){}
int getAge()
{
return this->_age;
}
private:
int _age;
};
int main(void)
{
Person p1(10);
cout << p1.getAge() << endl;
Person p2(20);
cout << p2.getAge() << endl;
return 0;
}
1.2 this指针的使用
1.当形参和成员变量同名时,可用this指针来区分
#include <iostream>
#include <cstring>
namespace myspace1
{
using std::endl;
using std::cout;
using std::cin;
using std::string;
}
using namespace myspace1;
//this:是指向当前对象的指针
//当前对象:谁调用这个函数,this指向谁;
//大多数情况下,this可以不写;
//使用
//1.当形参和成员变量同名时,可用this指针来区分
class Person
{
public:
//构造函数
Person():_age(0){}
Person(int age):_age(age){}
int getAge()
{
return this->_age;
}
void setAge(int _age)
{
_age = _age;
}
private:
int _age;
};
int main(void)
{
Person p1(10);
cout << p1.getAge() << endl;
p1.setAge(20);
cout << p1.getAge() << endl;
return 0;
}
可以看到,通过p1.setAge(20);并没有设置成功age的值;
void setAge(int _age)
{
this->_age = _age;
}
通过this指针,就可以修改了;
2.在类的非静态成员函数中返回对象本身,可使用return * this.
#include <iostream>
#include <cstring>
namespace myspace1
{
using std::endl;
using std::cout;
using std::cin;
using std::string;
}
using namespace myspace1;
//this:是指向当前对象的指针
//当前对象:谁调用这个函数,this指向谁;
//大多数情况下,this可以不写;
//使用
//1.当形参和成员变量同名时,可用this指针来区分
//2.在类的非静态成员函数中返回对象本身,可使用return * this
class Person
{
public:
//构造函数
Person() :_age(0) {}
Person(int age) :_age(age) {}
//设置一个函数,累加上一个数字,返回对象本身
Person& add(int age)
{
this->_age += age;
//返回当前对象的引用
return *this;
}
void print()
{
cout << this->_age << endl;
}
private:
int _age;
};
int main(void)
{
Person p1;
//每一次的函数调用,得到了自己(p1);
p1.add(10).add(20);//链式调用
p1.print();
return 0;
}
2. 特殊的数据成员
2.1 常量数据成员
当数据成员用 const 关键字进行修饰以后,就成为常量成员。一经初始化,该数据成员便具有“只读属性”,在程序中无法对其值修改(C++11之后也允许在声明时就初始化)。
#include <iostream>
#include <cstring>
namespace myspace1
{
using std::endl;
using std::cout;
using std::cin;
using std::string;
}
using namespace myspace1;
class Poin
{
public:
//构造函数
Poin(int x, int y) :_x(x), _y(y) //使用初始化列表来初始const数据成员
{
//错误,严格来说,这是赋值操作;
/*_x = x;
_y = y;*/
}
void print()
{
cout << "x=" << _x << endl;
cout << "y=" << _y << endl;
}
private:
const int _x;
const int _y;
//c++11允许在声明时,给默认值
/*const int _x = 1;
const int _y = 2;*/
};
void test(void)
{
Poin p1(10, 20);
p1.print();
//可以拷贝构造,但是不可以进行赋值操作;
Poin p2 = p1;
}
int main(void)
{
test();
return 0;
}
2.2 引用数据成员
#include <iostream>
#include <cstring>
namespace myspace1
{
using std::endl;
using std::cout;
using std::cin;
using std::string;
}
using namespace myspace1;
//int z=10;
class Poin
{
public:
//构造函数
//z的生命周期不够长,_z是其他值;
//解决办法
//1.将z定义为全局变量
//2.在定义时_z就绑定初值
Poin(int x, int y,int z) :_x(x), _y(y),_z(z)
{
}
void print()
{
cout << "x=" << _x << endl;
cout << "y=" << _y << endl;
cout << "z=" << _z << endl;
}
private:
int _x;
int _y;
int& _z;
//int &z=z; c++11标准
};
void test(void)
{
Poin p1(1, 2, 3);
p1.print();
}
int main(void)
{
test();
return 0;
}
2.3 静态数据成员
1.概念:
在一个类中,若将一个成员变量声明为static,这种成员称为静态成员变量。与一般的数据成员不同,无论建立了多少个对象,都只有一个静态数据的拷贝。静态成员变量,属于某个类,所有对象共享。
静态变量,是在编译阶段就分配空间,对象还没有创建时,就已经分配空间。
2.定义静态数据成员
class Pint {
public:
static int n; // 声明静态数据成员
};
3.初始化静态数据成员
class Pint {
public:
static int n; // 声明静态数据成员
};
// 在类外初始化静态数据成员
int Pint::n = 10;
void test(void)
{
cout << "n= " << Pint::n << endl;
}
int main(void)
{
test();
return 0;
}
4.访问静态数据成员
class Pint {
public:
static int n; // 声明静态数据成员
};
// 在类外初始化静态数据成员
int Pint::n = 10;
void test(void)
{
// 通过类名访问静态数据成员
cout << "n=" << Pint::n << endl;
// 通过对象访问静态数据成员
Pint p1;
cout << "n=" << p1.n << endl;
}
5.使用场景
(1)共享数据:当多个对象需要共享某个数据时,可以使用静态数据成员。例如,统计类的对象创建的数量。
(2)常量数据:如果类中有一些常量数据,并且希望所有对象都能访问这些常量,可以将其定义为静态数据成员。
2.4 对象成员
1.概念:
C++ 里,对象成员指的是一个类将其他类的对象作为自身的数据成员。借助这种方式,能够构建复杂的类结构,达成代码的复用与模块化设计。
#include <iostream>
#include <cstring>
namespace myspace1
{
using std::endl;
using std::cout;
using std::cin;
using std::string;
}
using namespace myspace1;
//汽车类
class Car
{
public:
//构造函数
Car():_color(new char[strlen("白色")+1]),_price(0) {
strcpy(_color, "白色");
cout << "Car无参构造函数" << endl;
}
Car(const char *color,int price):_color(new char[strlen(color) + 1]), _price(0){
strcpy(_color, color);
cout << "Car有参构造函数" << endl;
}
//析构函数
~Car()
{
if (_color != nullptr)
{
delete[] _color;
cout << "析构函数" << endl;
}
}
//写
void set(const char* color,int price)
{
strcpy(_color, color);
_price = price;
}
//打印
void print()
{
cout << "color=" << _color << endl;
cout << "pice=" << _price << endl;
}
private:
char* _color;
int _price;
};
//人类
class Person
{
public:
//构造函数
Person():_age(0){
cout << "Person无参构造函数" << endl;
}
Person(int age):_age(age)
{
cout << "Person有参构造函数" << endl;
}
void setAge(int age)
{
_age = age;
}
void printPerson()
{
cout << "age=" << _age << endl;
_c.print();
}
void setCar(const char* color, int price)
{
_c.set(color, price);
}
private:
Car _c;
int _age;
};
void test()
{
//Person 类的构造函数会先对其对象成员进行初始化,之后才执行自身构造函数体里的代码;
Person p1(20);
p1.setCar("黑色",20000); //设置车辆信息
p1.setAge(28); //设置年龄
p1.printPerson();
}
int main(void)
{
test();
return 0;
}
3. 特殊的成员函数
3.1 静态成员函数
1.概念:
在 C++ 中,静态成员函数是属于类而不是类的某个对象的成员函数。与普通成员函数不同,静态成员函数不依赖于特定的对象实例,它可以在没有创建任何对象的情况下被调用。
2.定义静态成员函数
//汽车类
class Car
{
public:
//静态成员函数
static void fun(void);
private:
char* _color;
int _price;
};
3.类外实现静态成员函数
//汽车类
class Car
{
public:
//静态成员函数
static void fun(void);
private:
char* _color;
int _price;
};
void Car::fun(void)
{
cout << "我是静态成员函数" << endl;
}
4.调用静态成员函数
静态成员函数可以通过类名直接调用,也可以通过类的对象调用
//汽车类
class Car
{
public:
//静态成员函数
static void fun(void);
private:
char* _color;
int _price;
};
void Car::fun(void)
{
cout << "我是静态成员函数" << endl;
}
void test()
{
//通过类名调用
Car::fun();
//通过对象调用
Car c1;
c1.fun();
}
int main(void)
{
test();
return 0;
}
5.使用场景
(1)工具函数:当一些函数与类的对象状态无关,只是提供一些通用的功能时,可以将其定义为静态成员函数。
(2)管理类的静态数据成员:当需要对类的静态数据成员进行操作时,可以使用静态成员函数。例如,统计类的对象创建的数量,使用静态成员函数来获取或修改这个统计值。
6.总结
(1)静态成员函数不依赖于某一个对象;
(2)静态成员函数可以通过对象调用,但更常见的方式是通过类名加上作用域限定符调用;
(3)静态成员函数没有this指针;
(4)静态成员函数中无法直接访问非静态的成员,只能访问静态数据成员或调用静态成员函数(因为没有this指针)。
(5)构造函数、拷贝构造、赋值运算符函数、析构函数比较特殊,可以在静态成员函数中调用。
3.2 const成员函数
1.概念
在 C++ 里,const 成员函数是一种特殊的成员函数,它承诺不会修改调用该函数的对象的状态
2.定义与语法
class Point {
private:
int value;
public:
Point(int val) : value(val) {}
// 声明 const 成员函数
int getValue() const;
};
// 定义 const 成员函数
//该函数内部不能修改对象的任何非静态数据成员。
int Point::getValue() const {
return value;
}
int main() {
const Point p1(10);
cout << "Value: " <<p1.getValue() << endl;
return 0;
}
3.使用场景
(1)访问器函数:当成员函数的主要目的是获取对象的某个属性值,而不修改对象的状态时,通常将其声明为 const 成员函数。
(2)在 const 对象上调用:如果你有一个 const 对象,那么只能调用该对象的 const 成员函数。因此,为了让 const 对象也能正常使用类的功能,需要将一些不修改对象状态的成员函数声明为 const 成员函数。
4.总结
(1)const 成员函数内部不能修改非静态数据成员
(2)const 成员函数和非 const 成员函数可以重载
3.3 mutable关键字
在 C++ 中,mutable 是一个关键字,它主要用于修饰类的数据成员。当一个数据成员被声明为 mutable 时,意味着即使在 const 成员函数中,该数据成员也可以被修改
class Point {
private:
mutable int _value;
public:
Point(int val) : _value(val) {}
// 声明 const 成员函数
int getValue() const;
};
// 定义 const 成员函数
int Point::getValue() const {
//可以被修改
_value = 100;
return _value;
}
int main() {
const Point p1(10);
cout << "Value: " <<p1.getValue() << endl;
return 0;
}