static members
一个类的static member也称为"class variable", 这是因为它是该类所有对象享的,即它的值不会因所属该类对象的不同而发生改变。
它可以用于统计目前该类实例化了多少对象:
#include <iostream>
using namespace std;
class Dummy {
public:
static int n;
Dummy () { n++; };
};
int Dummy::n=0;
int main () {
Dummy a;
Dummy b[5];
cout << a.n << '\n';
Dummy * c = new Dummy;
cout << Dummy::n << '\n';
delete c;
return 0;
}
由于static member的独特性,它禁止在类的内部被初始化,因为类的定义主要用于描述如何创建其对象和行为。但是static member不和任何对象绑定,因此它们的初始化必须分别对待。同时类中的static member仅仅是告知编译器它的存在,但是并没有为其分配存储空间。综上,为了给static member分配存储空间并且进行初始化,我们需要在类的外部进行这个操作,即
int Dummy::n=0;
对于static member functions而言,它们与static member variables类似,它们是该类所有对象公有的。因为对象需要创建才存在,而non- static member是和object绑定的。所以static member functions禁止访问non-static member (neither member variables nor member functions),当然也无法在函数内部使用this关键字。
Const member functions
当一个类的对象被限定为const时,从类的外部访问其member data时仅能进行read-only,但constructor仍然被自动调用来初始化和修改对象的data。
#include <iostream>
using namespace std;
class MyClass {
public:
int x;
MyClass(int val) : x(val) {}
int get() {return x;}
};
int main() {
const MyClass foo(10);
cout << foo.x << '\n';
return 0;
}
10
一个const限定的对象仅能调用其const限定的member functions。而限定member functions为const的方式为在参数列表后(),函数体前插入const关键字。例如:
int get() const {return x;}
值得注意的是,因为对象被const限定,因此我们无法修改此对象的state。而non-static members可能有修改其状态的风险,因此禁止const限定的member functions修改non-static data (可以访问)以及调用non-const member functions。
此外,一个类可以根据constness来对其member functions进行重载。在这种情况下,仅有const限定的object可以调用const版本的member function,其他情况的object调用non-const member function。
#include <iostream>
using namespace std;
class MyClass {
int x;
public:
MyClass(int val) : x(val) {}
const int& get() const { cout << "const version" << endl; return x;}
int& get() { cout << "non-const version" << endl; return x;}
};
int main() {
MyClass foo (10);
const MyClass bar (20);
foo.get() = 15;
cout << foo.get() << '\n';
cout << bar.get() << '\n';
return 0;
}
non-const version
non-const version
15
const version
20
更新(2024.4.8):
最近在写类的定义时,对于某个方法是否该使用const限定不是很确定,偶尔会报相关的错误,例如:
/Users/pengchen/CS106/Welcome/chapterExercises.cpp:34: error: 'this' argument to member function 'toString' has type 'const MyHashMap<int, std::string>', but function is not marked const
In file included from ../Welcome/chapterExercises.cpp:3:
../Welcome/myhashmap.h:392:18: error: 'this' argument to member function 'toString' has type 'const MyHashMap<int, std::string>', but function is not marked const
return os << hashmap.toString();
^~~~~~~
../Welcome/chapterExercises.cpp:34:10: note: in instantiation of function template specialization 'operator<<<int, std::string>' requested here
cout << mhp << endl;
^
../Welcome/myhashmap.h:110:17: note: 'toString' declared here
std::string toString();
^
所以继续更新自己对const使用的理解:
由ChatGPT的回答可以看出,如果该成员方法没有修改对象的状态时,就应该使用const限定。第三点原因比较诱人。