c++有时候需要为类的某个成员函数重载常量与非常量的版本,定义常量版本是为了保证该函数可作用于常量类对象上,并防止函数改动对象内容。但有时两个版本的函数仅仅是在返回的类型不同,而在返回前做了大量相同的工作,那么代码会有大量重复,由此也会带来编译时间和代码膨胀等开销。例如下面的类成员函数:
1 #include <string>
2
3 class Test
4 {
5 using size_type = std::string::size_type;
6 public:
7 const char & operator[](size_type index) const;
8 char & operator[](size_type index);
9 private:
10 std::string str;
11 };
12
13 const char & Test::operator[](size_type index) const
14 {
15 //...
16 //...
17 //要执行的操作
18 return str[index];
19 }
20
21 char & Test::operator[](size_type index)
22 {
23 //...
24 //...
25 //要执行的操作
26 return str[index];
27 }
虽然完全可以将执行的相同的动作写在一个新的成员函数里并将其定义为私有的,但这样仍然有函数调用和返回值的重复。一种可行的方法是让两个函数的其中一个调用另一个,如下所示:
1 class Test
2 {
3 using size_type = std::string::size_type;
4 public:
5 const char & operator[](size_type index) const;
6 char & operator[](size_type index);
7 private:
8 std::string str;
9 };
10
11 const char & Test::operator[](size_type index) const
12 {
13 //...
14 //...
15 //要执行的操作
16 return str[index];
17 }
18
19 char & Test::operator[](size_type index)
20 {
21 return const_cast<char &>(static_cast<const Test &>(*this)[index]);
22 }
非常量版本调用了常量版本,在这过程中进行了两次转型:
①static_cast
②const_cast
附注1:
应该注意函数调用的主宾关系:非常量版本调用常量版本并进行类型转换。反过来的做法则是一种错误的行为,常量版本成员函数不会改变对象的逻辑状态,而在常量版本中调用非常量版本则存在着可能改变对象的风险。实际上这样的代码若要通过编译,需要用const_cast去除*this的const属性,这显然是一种不安全的行为。相反,非常量版本成员函数本来就可以改动对象,因为在函数内部调用常量版本并不会有风险。
原文链接: https://www.cnblogs.com/jzincnblogs/p/5229416.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/229329
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!