静态成员函数问题请教

来源:百度知道 编辑:UC知道 时间:2024/06/19 10:22:47
#include <stdio.h>
#include <string.h>
class Base
{
private:
char * name;
public:
Base(char * className)
{
name = new char[strlen(className)];
strcpy(name, className);
}
~Base()
{
delete name;
}
char * getName()
{
return name;
}
static void print(Base base)
{
printf("name: %s\n" , base.name);
}
};
class Subclass : public Base
{
public:
Subclass(char * className) : Base(className)
{
}
};
int main()
{
Base * pBase = new Subclass("test");
Base::print(*pBase);
printf("name: %s\n", pBase->getName());
return 0;
}

执行结果是:
name: test
name:

经过调试确认是Base::print(*pBase);语句调用后导致name值被置空
屏蔽该语句或把static void print(Base base)改为static void print(Base &base)就执行正确了

搞不懂为什么会这样,请高手指教!!!

你往Base::print里传了一个非引用非指针的本类对象,那将导致在print中再建立一个Base对象,并且完全按位复制原对象,而这时两个类对象的.name将指向一个地方,你的print函数退出后,这个参数对象变量将调用析构,结果是name被delete,结果……复制构造函数是什么情况下必须写,你看看C++的书籍。另外,new中的长度应该是strlen结果+1,要给\0留位置。还有析构函数中的delete应该写delete [],还有main中要delete pBase;你没删除所以没有看出来一new一delete的结果,要不就是一new两delete了。错误太多,基础不牢啊。不是print的事儿。

其实并不是因为静态成员变量引起的,而是由于你没有提供拷贝构造函数。
调用Base::print(*pBase);时,将调用Base的默认拷贝构造函数,因为默认的拷贝构造函数是按位复制的,因此pBase的name地址被复制到了参数中的name,而参数中的Base对象在退出print时将执行析构函数把name空间释放掉,也即把pBase的name所指向的空间释放掉了,因此下面再调用就有可能出错.注意,你释放掉name空间时并没有赋值为NULL,因此其所指向的地址其实是不可知的。