c++禁止函数的传值调用的方法

所属分类: 软件编程 / C 语言 阅读数: 117
收藏 0 赞 0 分享

代码编译运行环境:VS2017+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);
}

以上程序顺利通过编译,并输出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);
}

这个程序在VS2017环境下编译不通过,得到如下错误: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. 需要产生一个临时类对象时(类对象作为函数返回值会创建临时对象)。

以上就是c++禁止函数的传值调用的方法的详细内容,更多关于c++禁止函数的传值调用的资料请关注脚本之家其它相关文章!

更多精彩内容其他人还在看

从汇编看c++中变量类型的深入分析

本篇文章是对c++中的变量类型进行了详细的分析介绍。需要的朋友参考下
收藏 0 赞 0 分享

从汇编看c++的默认析构函数的使用详解

本篇文章是对c++中默认析构函数的使用进行了详细的分析介绍。需要的朋友参考下
收藏 0 赞 0 分享

基于c++中的默认拷贝函数的使用详解

本篇文章对c++中默认拷贝函数的使用进行了详细的分析介绍。需要的朋友参考下
收藏 0 赞 0 分享

解析c++中的默认operator=操作的详解

本篇文章是对c++中的默认operator=操作的应用进行了详细的分析介绍。需要的朋友参考下
收藏 0 赞 0 分享

解析c++中参数对象与局部对象的析构顺序的详解

本篇文章是对c++中参数对象与局部对象的析构顺序进行了详细的分析介绍,需要的朋友参考下
收藏 0 赞 0 分享

深入c++中临时对象的析构时机的详解

本篇文章对c++中临时对象的析构时机进行了详细的分析介绍,需要的朋友参考下
收藏 0 赞 0 分享

解析内存对齐 Data alignment: Straighten up and fly right的详解

对于所有直接操作内存的程序员来说,数据对齐都是很重要的问题.数据对齐对你的程序的表现甚至能否正常运行都会产生影响
收藏 0 赞 0 分享

深入内存对齐的详解

本篇文章是对内存对齐进行了详细的分析介绍,需要的朋友参考下
收藏 0 赞 0 分享

深入C语言把文件读入字符串以及将字符串写入文件的解决方法

本篇文章是对C语言把文件读入字符串以及将字符串写入文件的方法进行了详细的分析介绍,需要的朋友参考下
收藏 0 赞 0 分享

深入Windows下的回车是回车换行(\r\n)还是换行回车(\n\r)的详解

本篇文章对Windows下的回车是回车换行(\r\n)还是换行回车(\n\r)进行了详细的分析介绍,需要的朋友参考下
收藏 0 赞 0 分享
查看更多