特殊的成员函数
大约 4 分钟
特殊的成员函数

除了特殊的数据成员以外,C++类中还有两种特殊的成员函数:静态成员函数和 const 成员函数。我们 先来看看静态成员函数。
静态成员函数
成员函数也可以定义成静态的,静态成员函数的特点:
静态的成员函数的第一个参数位置没有this指针
静态的成员函数不能访问非静态的数据成员和非静态的成员函数
非静态的成员函数静态的数据成员和静态的成员函数
静态成员函数可以使用类名加作用符的形式进行调用(静态成员函数的特殊用法)
如下:
普通的成员方法特点:编译器会添加一个this形参变量
class Computer
{
public:
Computer(const char * brand, double price)
: _brand(new char[strlen(brand) + 1]())
, _price(price)
{
_totalPrice += _price;
}
//...
static void printTotalPrice()
{
cout << "总价:" << _totalPrice << endl;
}
//...
private:
char * _brand;
double _price;
static double _totalPrice;
};
对于静态成员函数,还可以直接通过类名进行调用,这也是的方式:
int main(void)
{
Computer pc1("Huawei MateBook14", 5699);
pc1.print();
Computer::printTotalPrice();//通过类名直接调用
return 0;
}
下面让我们再来看一个有意思的例子:
#ifndef __COMPUTER_H__
#define __COMPUTER_H__
class Computer
{
public:
Computer(const char *brand, float price);
Computer(const Computer &rhs);
Computer &operator=(const Computer &rhs);
void setBrand(const char *brand);
void setPrice(float price);
static void printTotalPrice();
void print();
~Computer();
private:
char *_brand;//8
float _price;//4, 内存对齐
static float _totalPrice;//4静态的数据成员不占类的大小,被类
//创建的所有对象所共享
};
#endif
void test4()
{
cout << "sizeof(Computer) = " << sizeof(Computer) << endl;
cout << "一台电脑都没有购买 : " << endl;
Computer::printTotalPrice();
cout << endl;
Computer com1("huawei", 6000);
cout << "com1 = ";
com1.print();
cout << "购买第一台电脑总价 : " << endl;
com1.printTotalPrice();
Computer::printTotalPrice();
cout << endl;
Computer com2("xiaomi", 8000);
cout << "com2 = ";
com2.print();
cout << "购买第二台电脑总价 : " << endl;
com2.printTotalPrice();
com1.printTotalPrice();
Computer::printTotalPrice();//可以使用类名加作用域限定符进行调用
/* Computer::print();//error */
}
const成员函数
之前已经介绍了const在函数中的应用,实际上,const在类成员函数中还有种特殊的用法,把const关键 字放在函数的参数表和函数体之间(与之前介绍的const放在函数前修饰返回值不同),称为const成员 函数,其具有以下特点:
对于非const对象,既可以调用const版本的成员函数,可以调用非const版本的成员函数,情况下,调用非const版本的成员函数
const对象调用const版本的成员函数,不能调用非const版本的函数
const版本的成员函数与非const版本的成员函数可以重载,一般先写const版本的
const版本的成员函数具有只读特性,不能进行写操作,所以对于不修改数据成员的情况,可以将成员函数用const修饰
其格式为:
类型 函数名(参数列表) const
{
函数体
}
比如当给Computer类添加一个const的打印函数后,则其实现如下:
class Computer
{
public:
//...
//const版本的成员函数可以与非const版本的成员函数进行重载(this指针是不一样)
//一般建议先写出const版本的成员函数
void Computer::print(/* Computer * const this */)
{
/* this->_price = 10; */
/* printTotalPrice();//ok */
cout << "void print()" << endl;
printf("brand : %p\n", _brand);
cout << "brand : " << _brand << endl
<< "price : " << this->_price << endl;
}
void Computer::print(/* const Computer * const this */) const
{
/* this->_price = 10;//error */
cout << "void print() const " << endl;
printf("brand : %p\n", _brand);
cout << "brand : " << _brand << endl
<< "price : " << this->_price << endl;
}
};
void test5()
{
//非const对象既可以访问非const版本成员函数也可以访问
//const版本的成员函数,但是默认情况下访问非const版本
//的成员函数
Computer com1("huawei", 6000);
cout << "com1 = ";
com1.print();
cout << endl;
//const int number = 10;
//const对象只能访问const版本的成员函数,不能访问非const版本的成员函数
const Computer com2("xiaomi", 8000);
cout << "com2 = ";
com2.print();
}
为什么const成员无法调用普通成员方法?
因为const成员的this指针类型为const T * const this
,
普通成员方法要求传入的是T * const this
,相当于试图T* <= const T*
, 错误