构造函数的问题
#include <iostream>
using namespace std;
class String
{
public :
int len;
//默认构造函数
String()
{
cout < < "默认构造函数 String::String() " < <endl;
}
//构造函数
String(int l ){
cout < < "构造函数 String::String(int l) " < <endl;
len = l;
}
//拷贝构造函数
String(const String& str){
cout < < "拷贝构造函数 String::String(const String& str) " < <endl;
len = str.len;
}
//赋值运算符
void operator=(const String& str){
cout < < "赋值运算符 String::operator=(const String& str) " < <endl;
len = str.len;
}
~String()
{
cout < < "~~ " < <endl;
}
};
String cp(const String& str)
{
return String(str);
}
void main()
{
String a(10);
String c
cp(a);
cout < < "end of main " < <endl;
}
输出为:
构造函数 String::String(int l)
默认构造函数 String::String()
拷贝构造函数 String::String(const String& str)
~~
end of main
~~
~~
Press any key to continue
我把String类中的析构函数去掉后,输出变成了:
构造函数 String::String(int l)
默认构造函数 String::String()
拷贝构造函数 String::String(const String& str)
拷贝构造函数 String::String(const String& str)
end of main
晕死了,这跟析构函数有什么关系呢?
从函数返回对象时到底要调用几次构造函数呢?
[解决办法]
在我使用三种编译器(VC7.1、BC6.0及Gcc)对你的如上程序进行测试:
在有析构函数的情况和你相同,输出为;
构造函数 String::String(int l)
默认构造函数 String::String()
拷贝构造函数 String::String(const String& str)
~~
end of main
~~
~~
...
如你所说去掉析构函数,则输出:
构造函数 String::String(int l)
默认构造函数 String::String()
拷贝构造函数 String::String(const String& str)
end of main
不好意思,我觉得根本没有可以“晕”的地方!
如果如你所说的那样输出,则程序中会多一次考贝建构,但我们看不出程序中会有多于三个的对象建构,String的类实例(对象变量)只有三个分别是a、c及cp函数中的一个临时对象(匿名)!
事实上你那个析构函数是纯演示用途,就你的String类而言等同于无,所以也谈不上什么去掉析构函数而导至的编译器优化,另处在《Inside The C++ Object Model》中也没有谈到过有去掉析构函数而导致编译器优化的说法。
[解决办法]
这种构造与析构的过程其实只要把握好,应该没有什么问题...
以下是小生对楼主程序的结果分析...
String a(10);
这条语句调用了构造函数.因为赋予了参数10.显然应该调用的是那个非默认构造函数...所以会有如下输出:
构造函数 String::String(int l)
String c
这条语句与上面的功能相同都是申明一个String对像,不同的是这个对像会调用默认的构造函数.所以会有如下输出:
默认构造函数 String::String()
cp(a);
上面的这条显然是一个函数调用语句.因为楼主的函数申明里参数使用的是引用形式所以.这里在参数赋值时不会发生拷贝构造函数.
但楼主的函数cp()里有一条:return String(str);语句.该语句会产生一个临时变量保存str的值.这里的String(str)显然调用了拷贝构造函数.所以有如下输出:
拷贝构造函数 String::String(const String& str)
当退出这个cp()函数时,显然该临时变量应该被析构所以会调用该临时变量的析构函数输出:
~~
在函数调用结束后会遇到以下语句:
cout < < "end of main " < <endl;
所以会有输出:
end of main
当该cout语句结束后,遇到右大括号,程序结束.此时程序会收尾工作就是把在程序中生成的 "栈 "变量给销毁.理论上讲应该是先调用对像c的析构函数,然后再调用对像a的析构函数.所以会有如下输出:
~~
~~
然后程序等待结束...
Press any key to continue
以上说法如有不对之处请大大们指出来...谢谢...