在Effective C++
第03项中,尽可能使用const.
class Bigint
{
int _data[MAXLEN];
//...
public:
int& operator[](const int index) { return _data[index]; }
const int operator[](const int index) const { return _data[index]; }
//...
};
Run Code Online (Sandbox Code Playgroud)
const int operator[]
确实有所作为int& operator[]
.
但是关于:
int foo() { }
Run Code Online (Sandbox Code Playgroud)
和
const int foo() { }
Run Code Online (Sandbox Code Playgroud)
似乎他们是一样的.
我的问题是,为什么我们用const int operator[](const int index) const
而不是int operator[](const int index) const
?
Jam*_*nze 85
忽略非类型返回类型的顶级cv限定符.这意味着即使你写:
int const foo();
Run Code Online (Sandbox Code Playgroud)
返回类型是int
.如果返回类型是引用,当然,const
不再是顶级,并且区别在于:
int& operator[]( int index );
Run Code Online (Sandbox Code Playgroud)
和
int const& operator[]( int index ) const;
Run Code Online (Sandbox Code Playgroud)
很重要.(另请注意,在函数声明中,如上所述,任何顶级cv限定符也会被忽略.)
区别也与类类型的返回值有关:如果返回T const
,则调用者不能对返回的值调用非const函数,例如:
class Test
{
public:
void f();
void g() const;
};
Test ff();
Test const gg();
ff().f(); // legal
ff().g(); // legal
gg().f(); // **illegal**
gg().g(); // legal
Run Code Online (Sandbox Code Playgroud)
Bar*_*icz 35
您应该清楚地区分应用于返回值的const用法,参数和函数本身.
返回值
考虑const std::string SomeMethod() const
.它不允许使用该(std::string&&)
函数,因为它需要非const rvalue.换句话说,将始终复制返回的字符串.
const
保护返回的对象不被修改.参数
功能本身
const
在最后,它只能运行其他const
函数,并且不能修改或允许修改类数据.因此,如果它通过引用返回,则返回的引用必须是const.只能在对象上调用const函数或对const本身的对象进行引用.可变字段也可以更改.this
对引用的引用T const*
.该功能可以随时使用const_cast
this
,但当然不应该这样做并且被认为是不安全的.结论
如果您的方法没有并且永远不会修改类变量,请将其标记为const并确保满足所需的所有标准.它将允许编写更清晰的代码,从而保持其正确性.然而,把const
它放在任何地方而不给它任何想法肯定不是要走的路.
sbi*_*sbi 29
有没有什么价值的加入const
资格的非参考/非指针右值,并没有一点在其添加到内置插件.
对于用户定义的类型,const
限定条件将阻止调用者在返回的对象上调用非const
成员函数.例如,给定
const std::string foo();
std::string bar();
Run Code Online (Sandbox Code Playgroud)
然后
foo().resize(42);
Run Code Online (Sandbox Code Playgroud)
会被禁止,而
bar().resize(4711);
Run Code Online (Sandbox Code Playgroud)
会被允许的.
对于内置int
函数来说,这根本没有意义,因为无论如何都不能修改这样的rvalues.
(我记得C++有效讨论作出的返回类型operator=()
一个const
参考,不过,这是值得考虑的问题.)
编辑:
看来,斯科特确实给他的意见.如果是这样,那么由于上面给出的原因,我发现即使对于C++ 98和C++ 03也有问题.对于C++ 11,我认为这显然是错误的,正如Scott自己似乎已经发现的那样.在Effective C++的勘误表中,第3版.,他写道(或引用其他抱怨的人):
该文本暗示所有按值返回应该是const,但非常量按值返回是良好设计的情况并不难找到,例如,返回std :: vector类型,其中调用者将使用带有空向量的swap "抓取"返回值内容而不复制它们.
然后:
声明按值函数返回值const将阻止它们绑定到C++ 0x中的右值引用.因为rvalue引用旨在帮助提高C++代码的效率,所以在指定函数签名时考虑const返回值的交互和rvalue引用的初始化是很重要的.
And*_*rey 17
您可能会错过Meyers的建议.本质区别在于const
方法的修饰符.
这是一个非const方法(最后注意没有const
),这意味着允许修改类的状态.
int& operator[](const int index)
Run Code Online (Sandbox Code Playgroud)
这是一个const方法(最后的注意const
)
const int operator[](const int index) const
Run Code Online (Sandbox Code Playgroud)
参数的类型和返回值如何,int
和之间存在细微差别const int
,但与建议的要点无关.你应该注意的是,非const超载的回报int&
,这意味着你可以分配给它,比如num[i]=0
,和常量超载返回不可修改的值(无论返回类型int
或const int
).
在我个人看来,如果一个对象按值传递,则const
修饰符是多余的.此语法更短,并实现相同
int& operator[](int index);
int operator[](int index) const;
Run Code Online (Sandbox Code Playgroud)
在编写该书时,该建议几乎没用,但确实可以阻止用户编写,foo() = 42;
并期望它能够改变持久性的东西.
在这种情况下operator[]
,如果您还没有提供const
返回非const
引用的非重载,这可能会有点混乱,尽管您可以通过返回const
引用或代理对象而不是值来防止这种混淆.
这些天,这是一个糟糕的建议,因为它阻止您将结果绑定到(非const
)右值引用.
(正如评论中所指出的那样,回归原始类型时问题是没有意义的int
,因为语言阻止你分配给rvalue
这样的类型;我在谈论包括返回用户定义类型的更一般的情况. )
归档时间: |
|
查看次数: |
27664 次 |
最近记录: |