Cxx- 类的static member 和 const member

static members1

一个类的static member也称为"class variable", 这是因为它是该类所有对象中共享的,即它的值不会因所属该类对象的不同而发生改变。

它可以用于统计目前该类实例化了多少对象:

// static members in classes
#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;
}

6
7

由于static member的独特性,它禁止在类的内部被初始化2,因为类的定义主要用于描述如何创建其对象和行为。但是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 functions3

当一个类的对象被限定为const时,从类的外部访问其member data时仅能进行read-only,但constructor仍然被自动调用来初始化和修改对象的data。

// constructor on const object
#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);
// foo.x = 20;            // not valid: x cannot be modified
  cout << foo.x << '\n';  // ok: data member x can be read
  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。

// overloading members on constness
#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;         // ok: get() returns int&
// bar.get() = 25;        // not valid: get() returns const int&
    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使用的理解:

  1. C++中类的方法什么时候需要const限定

    在C++中,当你希望某个类的方法不修改类的成员变量时,应该在该方法的声明和定义处使用const限定符。这表明了该方法是一个常量成员函数,它保证不会改变对象的状态。这对于增强代码的安全性和明确方法的意图非常有帮助。具体来说,使用const限定的场景包括但不限于以下几点:
    1. 访问器方法(Accessor Methods):通常用于返回对象内部状态但不应该修改对象的方法。例如,获取成员变量的值的方法应该声明为const。
    2. 与const对象一起使用:当对象被声明为const时,只能调用其const成员函数。这是因为const对象不应被修改,而const成员函数保证了这一点。
    3. 提高方法的通用性:将方法声明为const可以使该方法既能被const对象调用,也能被非const对象调用,从而增加了方法的适用范围。
    4. 作为接口的一部分体现类的设计意图:在设计类时,通过合理使用const限定符可以向类的使用者明确哪些方法是安全的“只读”操作,哪些方法可能会修改对象的状态。

由ChatGPT的回答可以看出,如果该成员方法没有修改对象的状态时,就应该使用const限定。第三点原因比较诱人。


  1. https://legacy.cplusplus.com/doc/tutorial/templates/ ↩︎

  2. except for constexpr static members, which can be initialized inside the class since C++11 ↩︎

  3. https://legacy.cplusplus.com/doc/tutorial/templates/ ↩︎

  • 21
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ocodotial

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值