C++ Primer 第七章 7.6 类的静态成员 练习和总结

7.6 类的静态成员

我们有的时候希望,类的某一些数据成员和成员函数是和类相关,而不是和类的对象相关。

比如,Account类的汇率。所有的Account类的汇率都是一样的,当我们修改Account类的汇率时,所有对象都能访问这个更新的值。

所以我们需要类的静态数据成员和静态成员函数。

我们在普通的成员前,添加static关键字,表示这是一个静态的成员

class A {
public:
	int a;
	//静态数据成员
	static int b;
public:
	void func_1(int i = b) {
		cout<<i<<endl;
	};
	//静态成员函数
	static int static_func_1();
};

int A::static_func_1() {
	cout << b << endl;
	return 1;
}

int A::b = 1;

和普通的数据成员一样,静态的数据成员可以是public也可以时private,可以是类类型,也可以是引用或者指针类型。

静态的成员不属于任何一个对象,但是类的所有对象都可以访问静态的成员。

在类的外部,我们可以使用作用域运算符访问类的静态成员。我们也可以使用类的对象,引用或者指针来访问静态成员。

//访问数据成员
A::b;
//访问成员函数
A::static_func_1();

A data1;
data1.b;
data1.static_func_1();

A &data2 = data1;
data2.a;
data2.static_func_1();

A* data3_p = &data1;
data3_p->b;
data3_p->static_func_1();

在类的内部,可以直接访问类的静态成员,无需添加作用域运算符。

定义静态成员

1.对于静态数据成员,需要在类中进行声明,在类外定义,在类外定义时,不能添加static,static只能出现在类内部的声明语句中
2.对于静态成员函数,可以在类中定义,也可以在类外定义,在类外定义时,不能添加static关键字,static只能出现在类内部的声明语句中
3.静态成员函数中,不包含this指针,所以也就不能声明为const函数,应为const函数本来就是限制this指针的操作。

注意,在类的外部使用了作用域运算符之后,后面的作用域就是类的作用域了,这一点容易出错。

//A::,这条语句后面的作用域是A作用域。
int A::b = static_func_1();

之前说了,类的静态数据成员必须在类的内部声明,在类的进行初始化,但是如果这个数据成员是const类型或者是constexpr类型,则可以在类中进行初始化。

class A {
public:
	int a;
	static int b;
	const static int c = 2;
	constexpr static int d = 3;
public:
	void func_1(int i = b) {
		cout<<i<<endl;
		cout << c << endl;
		cout << d << endl;
	};
	static void static_func_1();
};
int A::b = 1;

void A::static_func_1() {
	cout << b << endl;
}

测试用例
A a;
a.func_1();
cout<<A::c<<endl;
cout<<A::d<<endl;

虽然const和constexpr的静态数据成员可以在类内初始化,也可以在类外直接访问,但是如果我们删除掉const或者constexpr,而没有在外部进行定义的化,则程序会报错,所以最好在外部也加上定义,此时外部的定义不能有初始值

A::c = 3;//报错,不能再指定初始值

静态成员和普通成员的区别
1.因为类的静态成员独立于任何一个对象。所以我们可以在类中定义类自己的静态数据成员。

class A{
//这是对的
	static A a;
	//这是错的
	A a;
};

2.我们可以使用静态数据成员作为默认实参,但是不能使用普通数据成员作为实参
3.我们可以在普通成员函数中调用静态成员和普通成员,但是在静态成员函数中,只能调用静态成员

练习

7.56

使用static修饰的数据成员和成员函数,是类的静态成员,它独立于类的所有对象,可以使用类名+作用域运算符直接访问。适用于类的公共属性或者操作。

区别:
1.静态数据成员可以默认实参,普通数据成员不可以
2.静态成员函数不能是const类型,普通成员函数可以,为什么,因为静态成员函数独立于对象,而this指针其实是对象调用成员函数时,对象自己的地址,静态成员独立于对象,所以没有this指针,而const函数又是限定this指针的操作的,所以静态成员函数不能声明为const。
3.普通成员函数可以调用静态成员,但是静态成员函数只能调用静态成员

7.57

class Account {
private:
	static double rate;
	string username;
	double money;
public:
	static double get_rate() { return rate; };
	Account() = default;
	Account(string u, double m=0.0) :username(u), money(m) {};
	string get_info() { return "username:" + username + "\nmoney:" + std::to_string(money); };
};
//在外部定义
double Account::rate = 1.23;

7.58
1.rate的定义是错的,只有const或者constexpr的静态数据成员可以在类中初始化
2.vec同理

你可能感兴趣的:(C++,C++,基础)