【学习交流】关于函数返回对象名与构造函数的调用
- C/C++ code
#include <iostream>using namespace std;class MyString{public: MyString(); MyString(char* str); MyString(const MyString& mstr); ~MyString(); MyString& operator=(const char* str); MyString& operator=(const MyString& str); friend ostream& operator<<(ostream& out, MyString& str); friend ostream& operator<<(ostream& out, const MyString& str);private://private、protected int size; static int count; char* data;};int MyString::count = 0;MyString::MyString(){ size = 0; data = new char[1]; strcpy(data, "\0"); cout << "构造函数:" << ++count << data << endl;//统计构造函数调用次数}MyString::MyString(char* str){ size = strlen(str); data = new char[strlen(str)+1]; strcpy(data, str); cout << "构造函数:" << ++count << data << endl;//统计构造函数调用次数}MyString::MyString(const MyString& mstr){ size = strlen(mstr.data); data = new char[strlen(mstr.data)+1]; strcpy(data, mstr.data); cout << "拷贝构造函数:" << ++count << data << endl;//统计构造函数调用次数,第2个构造函数析构后才调用拷贝构造函数}MyString::~MyString(){ cout << "析构函数" << count-- << data << endl; if(data!=NULL)delete []data; data = NULL;}MyString& MyString::operator=(const char* str){ //size = str.length(); //if(data==str) if(data!=NULL)delete []data;//释放原有内存 size = strlen(str); data = new char[size+1]; strcpy(data, str); return *this;}MyString& MyString::operator=(const MyString& str){ if(this==&str) return *this; if(data!=NULL)delete []data;//释放原有内存 size = strlen(str.data); data = new char[size+1]; strcpy(data, str.data); return *this;//返回类型为MyString类引用,操作类似:MyString& temp = *this;否则为MyString temp = *this;(会调用拷贝构造函数)}ostream& operator<<(ostream& out, MyString& str){//输出变量 out << str.data;//在友元函数内部,非类内部,类对象也可以访问私有成员; return out;}ostream& operator<<(ostream& out, const MyString& str){//输出常量,加个const也算是运算符重载,与函数重载不同 out << str.data;//在友元函数内部,非类内部,类对象也可以访问私有成员; return out;}/*const MyString& tempString(){ MyString str("Hi!!!"); return str;//const MyString& temp = str;temp是乱码???}*/const MyString& tempString(const MyString str){ return str;//const MyString& temp = str;temp是乱码???}void main(){ MyString str1("OK!!!"); //tempString();//测试函数返回值引用的作用,函数返回值为&的话,则tempString函数只调用一个构造函数;否则调用2个(拷贝)构造函数; //const MyString str2 = tempString();//①测试函数返回值引用的作用,发现拷贝构造函数调用之前str已经析构,str2为Hi!!! const MyString str2 = tempString("Hi!!!");//②测试函数返回值引用的作用,发现拷贝构造函数调用之前str已经析构,str2为乱码 //MyString& str2 = tempString();//出错 //str2 = "Haha!!!"; cout << "str2 = " << str2 << endl;}/*
const MyString& tempString(){
MyString str("Hi!!!");
return str;//const MyString& temp = str;temp是乱码???
}*/
const MyString& tempString(const MyString str){
return str;//const MyString& temp = str;temp是乱码???
}
void main(){
MyString str1("OK!!!");
//tempString();//测试函数返回值引用的作用,函数返回值为&的话,则tempString函数只调用一个构造函数;否则调用2个(拷贝)构造函数;
//const MyString str2 = tempString();//①测试函数返回值引用的作用,发现拷贝构造函数调用之前str已经析构,str2为Hi!!!const MyString str2 = tempString("Hi!!!");//②测试函数返回值引用的作用,发现拷贝构造函数调用之前str已经析构,str2为乱码//MyString& str2 = tempString();//出错
//str2 = "Haha!!!";
cout << "str2 = " << str2 << endl;
}
==============================================================================
不是返回值为const MyString&吗(不是说const &延长了临时对象的生命周期吗?),怎么调试时发现str在拷贝构造函数调用之前就析构了?而且发现str作为形参和局部变量,str2值也不同,一个为"Hi!!!",一个为乱码。
[解决办法]
你弄错了临时对象被hold的情形,这个临时对象必须与const引用在同一作用域内。
const MyString& tempString()导致str2引用了一个局部域中的对象,当然被析构了。这个函数应该这样声明:
const MyString tempString()
这样才是把tempString返回的临时对象绑定在str2上,并与str2具有相同的生存期。
[解决办法]
[解决办法]
同上底下的应该是这样
const MyString& tempString(const MyString & str){
return str;//const MyString& temp = str;temp是乱码???
}