c++重载时const的作用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++重载时const的作用相关的知识,希望对你有一定的参考价值。
class CA
public:
CA()
: n(0);
~CA();
private:
int n;
public:
int &getNum()
return n;
;
const int &getNum() const
return n;
;
;
这2个getNum有什么区别?
分别都是怎么调用的?
a.传递过来的参数在函数内不可以改变(无意义,因为Var本身就是形参)void function(const int Var); b.参数指针所指内容为常量不可变void function(const char* Var); c.参数指针本身为常量不可变(也无意义,因为char* Var也是形参)void function(char* const Var); d.参数为引用,为了增加效率同时防止修改。修饰引用参数时:void function(const Class& Var); //引用参数在函数内不可以改变void function(const TYPE& Var); //引用参数在函数内为常量不可变这样的一个const引用传递和最普通的函数按值传递的效果是一模一样的,他禁止对引用的对象的一切修改,唯一不同的是按值传递会先建立一个类对象的副本, 然后传递过去,而它直接传递地址,所以这种传递比按值传递更有效.另外只有引用的const传递可以传递一个临时对象,因为临时对象都是const属性, 且是不可见的,他短时间存在一个局部域中,所以不能使用指针,只有引用的const传递能够捕捉到这个家伙.
(2)const 修饰函数返回值
const修饰函数返回值其实用的并不是很多,它的含义和const修饰普通变量以及指针的含义基本相同。
a.const int fun1() //这个其实无意义,因为参数返回本身就是赋值。
b. const int * fun2() //调用时 const int *pValue = fun2();
//我们可以把fun2()看作成一个变量,即指针内容不可变。
c.int* const fun3() //调用时 int * const pValue = fun2();
//我们可以把fun2()看作成一个变量,即指针本身不可变。一般情况下,函数的返回值为某个对象时,如果将其声明为const时,多用于操作符的重载。通常,不建议用const修饰函数的返回值类型为某个对象或对某个对象引用的情况。原因如下:如果返回值为某个对象为const(const A test = A 实例)或某个对象的引用为const(const A& test = A实例) ,则返回值具有const属性,则返回实例只能访问类A中的公有(保护)数据成员和const成员函数,并且不允许对其进行赋值操作,这在一般情况下很少用到。 参考技术A const在函数中的含义是该值在此函数范围内“无法修改”。站在调用者的角度,所有的值传递都是无法修改实参的。
#include <iostream>
using namespace std;
class Y;
/* 下面两个函数具有相同语义,即a均是值拷贝,无法改变实参。 */
void Method1(int a)
void Method1(const int a) // error:redefinition
/* 同样的语义,对象拷贝 */
void Method2(Y y)
void Method2(const Y y) // error:redefinition
/* 下面两个函数具有不同语义,即后者无法改变实参,之所以使用引用,可能是因为不想拷贝,节省内存。 */
void Method3(int& a)
void Method3(const int& a)
void Method4(Y& y)
void Method4(const Y& y)
int main(int count,char * args[])
return 0;
参考技术B 这里有详细的解释。
http://blog.csdn.net/youoran/article/details/8517611本回答被提问者采纳
const 成员函数的重载解析 C++
【中文标题】const 成员函数的重载解析 C++【英文标题】:Overload resolution C++ for const member functions 【发布时间】:2014-02-23 12:03:16 【问题描述】:假设你有一个有两个成员函数的类 T
char foo() const ...
char foo() ...
.
我的理解是,当需要一个常数 T 时,我们会解析为 (1);对于非常量 T,我们解决 (2)。
-
对吗?
在此解析中调用了哪个规则? (参考标准很棒,但感谢提供有用的简短摘要)
注意事项:
我试图用谷歌搜索它,但我在 SO 上获得的旧命中是其他涉及 const 的重载解决方案的案例。但是,链接到一个旧的 SO 实际上解释了上述内容显然很棒。
在重新阅读 Stroustrup 的“C++ 编程语言”,第 2 版(“特别版”),第 11.12 节中的字符串/Cref 示例时出现了这个问题,p。 296. 由于 Stroustrup 如此精确,答案可能在前面的部分中,但我看不出在哪里。也非常欢迎参考 Stroustrup 中的部分(第二版最好,因为这是我拥有的)。第 10.2.6 节将 const 成员介绍为那些“不改变对象的值”的成员,这暗示了答案,但并没有让我觉得它是一个明确的解决指令。
【问题讨论】:
在高级视图中,您可以考虑编译器将执行的转换。成员函数将被转换为:char foo(T const *this)
和 char foo(T *this)
(详情暂且不谈)。
@David Rodriguez - dribeas:我明白了;而对于指针类型参数, const p 和 p 在重载决议中是有区别的,对吗?这确实给出了一些直觉。
我已经正确地重新格式化了您的问题。请花点时间阅读Markdown formatting help。
@Konrad Rudolph:感谢。问题是当我在远离计算机时使用 iPhone 时:我熟悉正确的格式,但已知手机会添加/删除不可打印的内容。它在我的手机上看起来正确,但不是。我通常在家编辑一次,但不想等到半夜才提问。
附加的T*
/ T const*
参数称为隐式对象参数(虽然它实际上是一个引用);我不明白为什么这应该是一个高级视图。隐式对象参数和实际函数参数之间存在一些细节差异,但 AFAIK 重载决议的大部分都平等地对待它们。见[over.match.funcs]
【参考方案1】:
在 N3242(我手头的标准草案)中,13.3.1 第 4 段说
隐式对象参数的类型是“对 cv X 的左值引用”,对于没有 ref-qualifier 或 & ref-qualifier
这意味着首先出现的隐式对象参数的类型是“对cv X
的左值引用”,其中X
是类,cv
是成员变量的cv限定(即常量或非常量)。然后,重载决议继续正常进行。
要查看重载解决过程,首先,它们都被列为“候选”函数,因为它们在正确的范围内并且具有正确的名称。
在const
的情况下,只有const
成员函数才能进入下一步(称为“生存能力”),因此它自动成为最佳选择。非常量成员函数不可行,因为您无法将 const
引用转换为非常量引用。
在非常量情况下,常量和非常量版本都是可行的,但非常量版本“更好”,因为下面引用了 13.3.3.2 第 3 段的第五条规则。
标准转换序列 S1 是比标准转换序列更好的转换序列 标准转换序列 S2 if ...
S1 和 S2 是引用绑定,而 除了*** cv 限定符之外,引用引用是相同的类型, 并且 S2 初始化的引用所指的类型更多 cv-qualified 比由 S1 初始化的引用的类型 参考。
【讨论】:
您的解释是有道理的,但是 (a) 引用不应该继续吗?它似乎是“if type is (...)”,但似乎错过了“then (...)”; (b) 引用适用于 tmember 函数,对吗? (引用仅表示功能。 抱歉,上面的句子中提到了它丢失了。现在有意义吗? 我看到你已经解决了(b)(谢谢); (一)呢? (或告诉我是否/为什么(a)无关紧要) 对不起,我不明白。我最近添加了更多上下文。基本上它是说,对于没有引用限定符(你的情况)声明的非静态成员函数,隐式对象参数是对 X 的引用,无论函数声明的 cv 状态是什么。我没有看到任何未满足的条件。 在那之后,重载决议将隐式对象参数视为与任何其他参数完全相同,只是它首先出现。以上是关于c++重载时const的作用的主要内容,如果未能解决你的问题,请参考以下文章
C++类和对象(构造函数析构函数拷贝构造函数赋值运算符重载Const成员)详细解读
C++类和对象(构造函数析构函数拷贝构造函数赋值运算符重载Const成员)详细解读
C++类和对象(构造函数析构函数拷贝构造函数赋值运算符重载Const成员)详细解读