C++核心准则之const常量

2023-06-01 0 1,012

如前所述自表达式”不容变”的优点,在他们的程式结构设计实践中,假如恰当采用C++中的自表达式,对提高流程的时效性和易用性都有非常大的协助。

自表达式原则的关键点:

尽量采用const表达式尽量采用const核心理念成员表达式 尽量传达const操作符和const提及尽量采用constexpr

1:尽量采用const表达式

不容变第一类更容易逻辑推理,因而多于在须要更动其值时才将第一类增设为非const。避免碰巧的或无法特别注意到的值变动。比如说常用的for循环式:

for (const int i : c) cout << i << \n; // just reading: const for (int i : c) cout << i << \n; // BAD: just reading

或者表达式返回值:

void fun() { int i =0; const int bound = 1000; // bound 不能被不幸修正。 for(int i=0;i<bound;i++) { … } }

个别情况

透过值传达的表达式参数极少发生发生改变,但也极少新闻稿为const。

void f(const char* p); // 有必要性,*p 是自表达式 void f(char * const p); // 没必要性 void g(const int i) { … } // 没必要性
特别注意,表达式参数是两个返回值,因而对它的更动是返回值

2: 尽量采用const核心理念成员表达式

核心理念成员表达式假如被记号为const,假如它发生改变了第一类的状况。这种能更准确地表明结构设计企图、更快的时效性、C++能捕捉更多严重错误,有时候还能提供更多更多的强化良机。

先看两个严重错误实例:

class Point { int x, y; public: int getx() { return x; } // BAD, should be const as it doesnt modify the objects state // … }; void f(const Point& pt) { int x = pt.getx(); // ERROR, doesnt compile because getx was not marked const }

将f表达式的参数去掉const,当然能解决上面的编译问题。但多于当被调用的表达式会修正第一类时,才假如这种做。代码的读者也会假设接受 非const T*或T&的表达式将修正所提及的第一类。即使现在没,那么以后可能会这种做。

特别注意:

有些代码/库可能并未遵守const原则。它可能提供更多了新闻稿T* t的表达式,即使这些表达式不能修正t。你能

更新库代码,恰当采用const–首选的长期解决方案透过const_cast抛弃const–最好避免提供更多包装表达式
void f(int* p); // old code: f() does not modify `*p` void f(const int* p) { f(const_cast<int*>(p)); } // wrapper
请特别注意,这个包装表达式解决方案是两个补丁,假如只在f()的新闻稿不能直接修正时采用。

特别注意:

const核心理念成员表达式能:

修正mutable核心理念成员 调用操作符第一类(或者智能操作符)的非const核心理念成员表达式
class DateNotifier { DataNotifier():notifyCnt(0){} public: void notify() { ++notifyCnt; } public: int notifyCnt; }; class Date { public: Data():dn(new DateNotifier()),udn(make_unique<DateNotifier>()){} ~Data(){delete dn;} const string& string_ref() const { if (string_val == “”) compute_string_rep(); dn->notify(); //能调用df的非const成员表达式 udn->notify(); //能透过智能操作符调用非const核心理念成员表达式 return string_val; } // … private: void compute_string_rep() const // compute string representation and place it in string_val { string_val = “2022/01/14”; } mutable string string_val; //mutable核心理念成员,能修正 DateNotifier * dn; unique_ptr<DateNotifier > udn; // … };

3:尽量传达const操作符和const提及

在结构设计表达式参数的时候,const 参数不仅能避免其被不幸更动,也能暗示该表达式不能更动该参数。

值传达的参数不须要const(见上)
void f(char* p); // does f modify *p? (assume it does) void g(const char* p); // g does not modify *p
传达指向非const第一类的操作符或提及本身并不是坏事,但多于当被调用的表达式假如修正第一类时,才假如这种做。

4: 尽量采用constexpr

constexpr是c++11新增关键字。它与const的根本区别是:

const — 运行期确定的自表达式

constexpr — C++确定的自表达式

constexpr带来的好处是:更快的性能,更快的编译时检查,有保证的编译时计算,没竞争条件的可能性

例:

double x = f(); // possible run-time evaluation const double y = f(); // possible run-time evaluation constexpr double z = f(); // error unless f(2) can be evaluated at compile time
假如还是不理解运行期和C++的区别,这种思考:f() 假如是返回实时系统时间,那么返回值一定是运行期才能确定的。f()假如是返回圆周率,那么显然其返回值编译期就是能确定的。

参考:

CppCoreGuidelines/CppCoreGuidelines.md at master · isocpp/CppCoreGuidelines

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务