在 constness 和 volatility 上過載
如果可能,將指標引數傳遞給 T*
引數比將其傳遞給 const T*
引數更好。
struct Base {};
struct Derived : Base {};
void f(Base* pb);
void f(const Base* pb);
void f(const Derived* pd);
void f(bool b);
Base b;
f(&b); // f(Base*) is better than f(const Base*)
Derived d;
f(&d); // f(const Derived*) is better than f(Base*) though;
// constness is only a "tie-breaker" rule
同樣,如果可能的話,將引數傳遞給 T&
引數比將其傳遞給 const T&
引數更好,即使兩者都具有完全匹配等級。
void f(int& r);
void f(const int& r);
int x;
f(x); // both overloads match exactly, but f(int&) is still better
const int y = 42;
f(y); // only f(const int&) is viable
此規則也適用於 const 限定的成員函式,其中允許對非 const 物件的可變訪問和對 const 物件的不可變訪問非常重要。
class IntVector {
public:
// ...
int* data() { return m_data; }
const int* data() const { return m_data; }
private:
// ...
int* m_data;
};
IntVector v1;
int* data1 = v1.data(); // Vector::data() is better than Vector::data() const;
// data1 can be used to modify the vector's data
const IntVector v2;
const int* data2 = v2.data(); // only Vector::data() const is viable;
// data2 can't be used to modify the vector's data
以相同的方式,易失性過載將不如非易失性過載優選。
class AtomicInt {
public:
// ...
int load();
int load() volatile;
private:
// ...
};
AtomicInt a1;
a1.load(); // non-volatile overload preferred; no side effect
volatile AtomicInt a2;
a2.load(); // only volatile overload is viable; side effect
static_cast<volatile AtomicInt&>(a1).load(); // force volatile semantics for a1