如何禁止函数的传值调用
来源:互联网 发布:商场中指示牌软件 编辑:程序博客网 时间:2024/05/14 01:06
代码编译运行环境:VS2012+Debug+Win32
按照参数形式的不同,C++应该有三种函数调用方式:传值调用、引用调用和指针调用。对于基本数据类型的变量作为实参进行参数传递时,采用传值调用与引用调用和指针调用的效率相差不大。但是,对于类类型来说,传值调用和引用调用之间的区别很大,类对象的尺寸越大,这种差别越大。
传值调用与后面两者的区别在于传值调用在进入函数体之前,会在栈上建立一个实参的副本,而引用和指针滴啊用没有这个动作。建立副本的操作是利用拷贝构造函数进行的。因此,要禁止传值调用,就必须在类的拷贝构造函数上做文章。
可以直接在拷贝构造函数中跑出异常,这样就迫使程序员不能使用拷贝构造函数,否则程序总是出现运行时错误。但是,这不是一个好的办法,应该在编译的阶段就告诉程序员,不能使用该类的拷贝构造函数。
1.不显示定义拷贝构造函数可行吗?
#include <iostream>using namespace std;class A{public: int num; A(){num=5;}};void show(A a){ cout<<a.num<<endl;}int main(){ A obj; show(obj); getchar();}
以上程序顺利通过编译,并输出5。因此,不显示定义拷贝构造函数,并不能阻止对类的拷贝构造函数的调用,原因是编译器会自动为没有显示定义拷贝构造函数的类提供一个默认的拷贝构造函数。
2.显示定义拷贝构造函数并将访问权限设置为private
上面的程序添加拷贝构造函数的定义,修改如下。
#include <iostream>using namespace std;class A{ A(const A&){};public: int num; A(){num=5;}};void show(A a){ cout<<a.num<<endl;}int main(){ A obj; show(obj); getchar();}
这个程序在VS2012环境下编译不通过,得到如下错误:error C2248: “A::A”: 无法访问 private 成员(在“A”类中声明)。
这样就能阻止了函数调用时,类A的对象以值传递的方式进行函数函数调用。为使程序通过编译,需将show()函数的定义改为如下形式:
void show(const A& a){ cout<<a.num<<endl;}
3.拷贝构造函数的说明
(1)如果将拷贝构造函数中的引用符号去掉&,编译将无法通过,出错的信息如下:非法的复制构造函数: 第一个参数不应是“A”。原因是如果拷贝构造函数中的参数不是一个引用,即形如A(const A a),那么就相当于采用了传值的方式(pass-by-value),而传值的方式会调用该类的拷贝构造函数,从而造成无穷递归地调用拷贝构造函数。因此拷贝构造函数的参数必须是一个引用或一个指针。
(2)拷贝构造函数的参数且通常情况下是const的,但是const并不是严格必须的。
(3)以下几种情况会调用拷贝构造函数:
附带说明,在下面几种情况下会调用拷贝构造函数:
a. 显式或隐式地用同类型的一个对象来初始化另外一个对象;
b. 作为实参以值传递的方式传递给一个函数;
c. 在函数体内返回一个对象时,也会调用返回值类型的拷贝构造函数;
d. 需要产生一个临时类对象时(类对象作为函数返回值会创建临时对象)。
参考文献
[1]陈刚.C++高级进阶教程[M].武汉:武汉大学出版社,2008.[3.5(P102-P103)]
[2]http://www.cnblogs.com/hnrainll/archive/2011/05/17/2048620.html
- 如何禁止函数的传值调用
- 函数是如何调用的
- 禁止cookie如何获得session的值
- 如何让EditText禁止调用小键盘
- C++函数的传值调用&指针调用&引用调用
- 如何编译时禁止多余部分分配空间(如:禁止未调用函数参与编译)避免浪费code空间和警告?
- c++函数如何返回多值,返回数组的函数该如何调用
- 【win32 app调用html方法】解决VS2008中CHtmlView函数OnBeforeNavigate2不能禁止跳转的BUG
- javascript两种禁止一个函数没有运行结束时就再次调用的方法
- 如何禁止类的拷贝构造函数和复制构造函数
- Python中如何禁止函数修改列表
- main函数是如何被调用的
- 如何调用未知接口的dll函数
- 如何使EnableMenuItem函数的调用有效
- 如何使EnableMenuItem函数的调用有效
- 如何调用未公开的API函数
- 如何调用未公开的API函数
- 内核是如何调用OEMInterruptHandler函数的?
- linux ps 命令参数详解
- PHP 中 9 大缓存技术总结
- 「Linux命令行」sed
- hihocoder #1040 矩形判断
- android的linearlayout
- 如何禁止函数的传值调用
- 【Linux】RedHat9.0添加module和编译内核
- Hibernate3.6 入门(笔记二):映射_inverse_lazy
- tcpdump+wireshark分析数据笔记(2)
- 关于validate验证表单与js语法的一个bug
- lightoj 1154 - Penguins 【拆点建图后枚举汇点 满流判可行解】
- 函数指针与指针函数
- OpenCV之滑动条
- C#程序员经常用到的10个实用代码片段