stackoverflow上的一个关于传递类对象的问题

今天在stackoverflow上看到有一个这样提问

说下面这段程序第二个输出语句有问题

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

class C {
public:
char* s;
C(char* s_) {
s=(char *)calloc(strlen(s_)+1,1);
strcpy(s,s_);
};
~C() {
free(s);
};
};

void func(C c) {};

void main() {
C o="hello";
printf("hello: %s\n",o.s); // works ok
func(o);
printf("hello: %s\n",o.s); // outputs garbage
};


我看了以后,大概分析了一下,原因是这样的

在c++中如果如果我们给一个类的对象赋值,或当形参传给其他函数时,假如类中含有指针类型的变量,默认c++会为我们拷贝指针而不会拷贝指针指向的内容。

上面的例子中,

 func(o);
这个函数将实参o传给了形参,但是由于o的成员s是指针,所以实参与形参的指针指向了同一块内存空间,但是形参在函数结束后就析构掉了,
 free(s);同时把指向的内存空间也清除了,所以当主程序再次返回的时候,原来的指针指向的内存空间已经没有了数据,故输出错误。
下面是一个外国同行写的解决方案
#include <iostream>

class C {
std::string s;
C(const std::string& s_)
: s(s_){}
};

std::ostream& operator<<(std::ostream& os, const C& c){
return os << c.s;
}

void func(C& c){
// do what you need here
}

int main(){
C c("hello");
std::cout << c << '\n';
func(c);
std::cout << c << std::endl;
return 0;
}
他这样的写法,是从另外一个角度写的,没有解决了指针的问题,其实,我感觉更好的方法是写一个复制构造函数,去专门管理指针的赋值。这样就不会容易出错了。

posted @ 2012-03-10 00:36  雪狼的程序故事  阅读(1419)  评论(5编辑  收藏  举报