C++中的值参与引用的小问题

本文讲述了在C/C++函数调用时参数传递的问题。作者起初受Pascal影响,认为函数调用前后参数值不变用值参,改变用形参引用,但实践中发现错误。通过示例代码分析,指出副本析构导致原对象字符串被清空,将函数参数改为引用可解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以前在学校学Pascal的时候,产生了一种习惯性的思维:在函数调用时,如果在函数调用前后,不希望参数的值发生改变,那么使用值参;如果希望发生改变,那么使用形参。
在C/C++中,不存在形参,都是值传递的,而引用类似于Pascal中的形参。(我不知道这样说是否恰当)。所以,用C++的时候,我就有这种思维方式:在函数调用时,如果在函数调用前后,不希望参数的值发生改变,那么使用值参;如果希望发生改变,那么使用形参引用。

今天的一个偶然的错误,原来我的想法不对。
问题简化,以下是一个类的定义和实现:

class CA
{
public:
CA(char *a_pcChar = "Test");
virtual ~CA();

private:
char *m_pcChar;
};


CA::CA(char *a_pcChar)
{
if(a_pcChar == NULL)
{
m_pcChar = NULL;
return;
}
m_pcChar = new char[256];
memset(m_pcChar,'\0',sizeof(char) * 256);
strcpy(m_pcChar,a_pcChar);
}

CA::~CA()
{
if(m_pcChar != NULL)
{
delete []m_pcChar;
m_pcChar = NULL;
}
}

然后再定义一个函数:
void test(CA a_clsA)
{
int i = 0;
}


当执行如下代码:
CA clsTmpA("HelloWorld");
test(clsTmpA);

原意是:clsTmpA.m_pcChar 所指的字符串仍然是“HelloWorld”,然而事与愿违的是clsTmpA.m_pcChar所值的字符串的值竟然被清掉了。

为什么会这样呢?
思来想去,终于弄明白了。
在执行函数test(clsTmpA)的时候,编译器创建一个clsTmpA的副本,当然,这个副本的m_pcChar所指的地址当然与clsTmpA.m_pcChar的地址相同,此时它们所指向的字符串也是相同的。
但是,当test函数执行完毕退出这个函数时,这个副本也随之消失,因而会执行类CA的修够函数,所以这个副本的m_pcChar指向地址被释放。由于,副本的m_pcChar和clsTmpA.m_pcChar指向的地址相同,在退出函数时,clsTmpA.m_pcChar所指向的字符串被清空也是理所当然的了。

那么,问题怎么解决呢!
把函数 void test(CA a_clsA)改成 void test(CA &a_clsA)就解决了。对于修改后的情况,因为参数就是个函数本身(不是副本),所以在test执行完毕,也不会调用其析构函数。

用VC试试,果真如此,OK!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值