运维开发网

C++成员函数中const用法的详细介绍

运维开发网 https://www.qedev.com 2022-10-30 20:32 出处:网络
这篇文章主要为大家详细介绍了C++成员函数中const的使用,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

这篇文章主要为大家详细介绍了C++成员函数中const的使用,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

Const是C++中一个非常重要的关键字。它不仅可以用来修改变量,还可以用来定义函数。这里整理出const在函数中的三种用法。


修饰入参

首先我们要明白,在C++中调用函数有两种方法,即传值和传引用。


值传递

传递值时,调用函数时会创建参数的副本,函数中的操作不会修改原始值。所以没必要用const来这样修饰参数,因为它只对复制的临时对象起作用。


址传递

传递地址时,函数中的操作实际上是直接修改了原值,所以我们可以用const来修改这里的参数。


const修饰入参

当const修改一个函数时,意味着参数不能被修改。这是最好的理解。例如,如果一个函数的功能是复制,那么参数中的源文件将用const修改。

void A::show(const int *b) { cout lt;lt; "show const"; // error: read-only variable is not assignable // *b = 2; cout lt;lt; b lt;lt; endl;}

接下来要注意const在函数重载中的作用。在此,我们给出一个结论,欢迎讨论。对于应该通过值传递的函数,const不会有重载的效果,但是传递指针和引用会有重载的效果。

void A::show(const int b)// void A::show(int b) // error class member cannot be redeclaredvoid display(int *num); // overloadvoid display(const int *num); // overloadvoid fun(A amp;a); // overloadvoid fun(const A amp;a); // overload

函数重载的关键是函数的参数列表;;也就是函数签名。如果两个函数的参数个数和类型相同,参数的顺序相同,那么它们的特性相同,变量名无关。

总结一下注意事项:

如果输入参数采用ldquo;值传递rdquo;,**由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加 const 修饰。**例如不要将函数void Func1(int x)写成void Func1(const int x)。如果参数作为输出参数,不论它是什么数据类型,也不论它采用ldquo;指针传递rdquo;还是ldquo;引用传递rdquo;,都不能加 const 修饰,否则该参数将失去输出功能(因为有 const 修饰之后,不能改变他的值)。如果参数作为输入参数,可以防止数据被改变,起到保护作用,增加程序的健壮性,建议是能加const尽量加上

上述测试代码如下:

#include lt;iostreamgt;using namespace std;class A {private: int a;public: A(int a) { this-gt;a = a; } void show(int b); // error redeclared // void show(const int b); void display(int *num); // ok void display(const int *num); // ok void fun(A amp;a); void fun(const A amp;a); void happy(int * h); void hour(const int * h);};void A::show(int b) { cout lt;lt; "show: " lt;lt; b lt;lt; endl;}void A::display(int *num) { cout lt;lt; "display:" lt;lt; *num lt;lt; endl;}void A::display(const int *num) { cout lt;lt; "const display:" lt;lt; *num lt;lt; endl;}void A::fun(A amp;obj) { cout lt;lt; "fun: " lt;lt; obj.a lt;lt; endl;}void A::fun(const A amp;obj) { cout lt;lt; "const fun: " lt;lt; obj.a lt;lt; endl;}void A::happy(int *h) { cout lt;lt; "happy:" lt;lt; *h lt;lt; endl;}void A::hour(const int *h) { cout lt;lt; "const hour:" lt;lt; *h lt;lt; endl;}int main() { A a(1); const A a2(11); int b1 = 2; const int b2 = 3; // test overload a.show(b1); a.show(b2); a.display(amp;b1); a.display(amp;b2); a.fun(a); a.fun(a2); // test const a.happy(amp;b1); // a.happy(amp;b2); // error cannot initialize a parameter of type 'int *' with an rvalue of type 'const int *' a.hour(amp;b1); a.hour(amp;b2); return 0;}// ouptutshow: 2show: 3display:2const display:3fun: 1const fun: 11happy:2const hour:2const hour:3


修饰返回值

当const修饰返回值时,意味着不能修改返回值。注意,如果函数的返回值采用ldquo价值转移模式rdquo因为函数会将返回值复制到外部临时存储单元,所以添加const decoration没有任何价值。如果返回引用或指针,则不能修改指向的数据。

通常,返回值是引用的函数被广泛使用。可以肯定的是,这个引用一定不是临时对象的引用,所以一定是成员变量或者函数参数。所以为了防止返回时被修改为左值,需要添加const关键字进行修改。

我们可以看看下面的代码示例:

#include lt;iostreamgt;using namespace std;class Alice {private: int a;public: Alice(int a): a(a) {} int get_a() {return a;} const int* get_const_ptr() {return amp;a;} int* get_ptr() {return amp;a;}};int main() { Alice alice(1); int a1 = alice.get_a(); // ok cout lt;lt; a1 lt;lt; endl; const int a2 = alice.get_a(); // ok cout lt;lt; a2 lt;lt; endl; // error cannot initialize a variable of type 'int *' with an rvalue of type 'const int *' // int* b1 = alice.get_const_ptr(); const int* b2 = alice.get_const_ptr(); // ok cout lt;lt; *b2 lt;lt; endl; // ok // *b2 = 3; // error read-only variable is not assignable *(alice.get_ptr()) = 3; cout lt;lt; alice.get_a() lt;lt; endl; // 3 return 0;}


修饰函数

Const也可以用在函数的末尾,用来修饰成员函数,表示它是一个常量成员函数。这对于刚接触C++的同学来说会有点陌生,但也是C++严谨的地方。先看代码示例。在学习任何编程技术时,都必须编写相应的代码。只有运行它,分析结果,你才能真正学会它。不是,你只是知道这个知识点,却不知道为什么。纸上谈兵很难学,但是不知道怎么做。在这里做就是写代码。

让我们先来看看下面的代码

class Alice {private: int a;public: Alice(int a): a(a) {} void show();};void Alice::show() { cout lt;lt; "hello Alice" lt;lt; endl;}int main() { const Alice a(1); // error: 'this' argument to member function 'show' has type 'const Alice', but function is not marked const // a.show(); return 0;}

上面的代码会报错,因为show()方法不是常量成员函数,a是常量对象。本质上,每个成员函数都有一个隐式参数this,它引用调用该方法的对象。如果在函数后面加上const,这个const实际上修改了this this。也就是说,函数后面加了const,表示这个函数不会改变调用者对象。

这有一张侯杰先生的照片。


上图显示,正常情况下:

non-const对象可以调用const 或者 non-const 成员函数const 对象 只可以调用 const 成员函数

添加,* *如果成员函数同时有const和非常数版本,则const对象只能调用const成员函数,非常数对象只能调用非常数成员函数。* *如下面的代码示例所示

#include lt;iostreamgt;using namespace std;class R {public: R(int r1, int r2) { a = r1; b = r2; } void print(); void print() const;private: int a; int b;};void R::print() { cout lt;lt; "normal print" lt;lt; endl; cout lt;lt; a lt;lt; ", " lt;lt; b lt;lt; endl;}void R::print() const { cout lt;lt; "const print" lt;lt; endl; cout lt;lt; a lt;lt; ", " lt;lt; b lt;lt; endl;}int main() { R a(5, 3); a.print(); const R b(6 ,6); b.print(); return 0;}// outputnormal print5, 3const print6, 6

这里还有一个建议,尽可能的增加const。


总结

本文到此为止。

0

上一篇:

没有了:下一篇

精彩评论

暂无评论...
验证码 换一张
取 消