/
// Filename: mystring.h
/
#ifndef _MYSTRING_H_
#define _MYSTRING_H_
#include <iostream>
using namespace std;
class CMystring
{
public:
CMystring();
CMystring( const char* str );
CMystring( const CMystring& );
CMystring& operator=( const CMystring& other );
friend CMystring operator+( const CMystring& s1, const CMystring& s2 ); // 没有friend修饰,参数只能是一个,如下
//CMystring operator+( const CMystring& s2 );
friend ostream& operator<<( ostream& o, const CMystring &str );
private:
char* m_data;
};
#endif
//
// Filename: mystring.cpp
///
#include "mystring.h"
CMystring::CMystring()
{
m_data = NULL;
m_data = new char[1];
if( m_data == NULL )
{
cout << "不能分配内存!" << endl;
}
else
{
m_data[0] = '\0';
}
}
CMystring::CMystring( const char* str )
{
cout << "CMystring(const char* str):" << this << endl;
if( str == NULL )
{
m_data = NULL;
m_data = new char[1];
if( m_data == NULL )
{
cout << "不能分配内存" << endl;
}
else
{
m_data[0] = '\0';
}
}
else
{
int length = strlen(str);
m_data = NULL;
m_data = new char[ length+1 ];
if( m_data == NULL )
{
cout << "不能分配内存" << endl;
}
else
{
strcpy( m_data, str );
}
}
}
CMystring& CMystring::operator=( const CMystring& other )
{
cout << "= func parameter:" << &other << endl;
if( this == &other ) // 检查自身赋值
{
return *this;
}
if( m_data != NULL )
{
delete []m_data; // 释放原有的空间
m_data = NULL;
}
m_data = new char[ strlen(other.m_data)+1 ];
if( m_data == NULL )
{
cout << "不能分配空间!" << endl;
return *this;
}
else
{
strcpy( m_data, other.m_data );
return *this;
}
}
CMystring::CMystring( const CMystring &str)
{
cout << "copy112 constructor:" << this << endl;
cout << "parameter addr: " << &str << endl;
m_data = new char[ strlen(str.m_data) + 1 ];
//delete []m_data;出错原因:对象并没有调用构造函数
if( m_data == NULL )
{
cout << "can not allocate memory!" << endl;
system("pause");
}
strcpy( m_data, str.m_data );
}
CMystring operator+( const CMystring& s1, const CMystring& s2 )
{
CMystring temp;
delete []temp.m_data; // temp是只含'\0'的空字符串
temp.m_data = NULL;
temp.m_data = new char[ strlen(s1.m_data) + strlen(s2.m_data) + 1 ];
if( temp.m_data == NULL )
{
cout << "不能分配内存!" << endl;
CMystring retTemp;
return retTemp;
}
else
{
strcpy( temp.m_data, s1.m_data );
strcat( temp.m_data, s2.m_data );
cout << "+ func return:" << &temp << endl;
return temp;
}
}
ostream& operator<<( ostream &o, const CMystring &str )
{
o << str.m_data;
return o;
}
/*
CMystring CMystring::operator+( const CMystring &s2 )
{
CMystring temp;
delete []temp.m_data;
temp.m_data = NULL;
temp.m_data = new char[ strlen(m_data) + strlen(s2.m_data) + 1 ];
if( temp.m_data == NULL )
{
cout << "不能分配内存!" << endl;
CMystring retTemp;
return retTemp;
}
else
{
strcpy( temp.m_data, m_data );
strcat( temp.m_data, s2.m_data );
cout << "+ func return:" << &temp << endl;
return temp;
}
}
*/
//
// Filename: main.cpp
/
#include "mystring.h"
#include <string>
CMystring getStr1()
{
CMystring s1 = "hello ";
CMystring s2 = "world";
//在外部存储单元中新建临时变量s1+s2
return CMystring(s1 + s2);
}
CMystring getStr2()
{
CMystring s1 = "hello ";
CMystring s2 = "world";
CMystring temp = "";
temp = s1 + s2;
//调用拷贝构造函数把temp的值复制给外部一个临时变量中
return temp;
}
int main()
{
// 这里在 getStr1返回 时创建的变量就是 ss1,进行了优化 ,而不必先在外部创建临时对象,然后调用拷贝构造函数构造 ss1
// 编译器可以选择跳过拷贝的过程而直接将拷贝的终点对象作为构造的对象,而不必考虑因此带来的任何副作用。
CMystring ss1 = getStr1();
cout << &ss1 << endl;
cout << ss1 << endl;
// 用外部返回的临时变量调用拷贝构造函数复制给s2,用了两次拷贝构造函数,这里也会优化 ,也会只调用一次
CMystring ss2 = getStr2();
cout << &ss2 << endl;
cout << ss2 << endl;
cout << "------------------------1-------------------------------------------" << endl << endl;
const string &ss = "sdf"; // 将用sdf创建一个临时对象,而临时对象只能是const 类型
CMystring s1("hello");
CMystring s2(" world!");
CMystring s3("df");
s3 = s2 = s1;
// s1+s2返回时将在外部用拷贝构造函数构造一个CMystring临时对象(用s1+s2函数的返回值作为参数)
// 在外部构造的对象将作为参数传给赋值函数,完成赋值
s3 = s1 + s2;
// 这里s1+s2返回时也会在外部用拷贝构造函数构造一个临时对象,而str为这个对象的引用
// 这个临时对象为const类型,所以为const引用 ,设置断点调试这个临时对象的构造过程时,
//在拷贝构造函数中设置了断点,但程序也没有在该断点处暂停 但拷贝构造函数却有执行过
const CMystring& str = s1 + s2;
cout << &str << endl; // 这里的地址与s1+s2返回时构造的临时对象的地址相同
cout << "------------------------2-------------------------------------------" << endl << endl;
cout << "begin:" << endl;
CMystring s4 = "abc"; // 等价于CMystring s4 = CMystring("abc"); 但没有执行拷贝构造函数呢,只
// 执行了CMystring( const char* str ); 原因是编译器对其优化了?
cout << "s4:" << &s4 << endl;
cout << "end:" << endl;
cout << "------------------------3-------------------------------------------" << endl << endl;
CMystring s5("abcd"); // 会调用构造函数:CMystring( const char* str )
CMystring s6("1234");
cout << "test begin:" << endl;
// 本来s5+s6返回时在外部调用拷贝构造函数 构造一个临时对象,然后再调用拷贝构造函数构造s7,
// 共两次拷贝构造函数,但实际上编译器进行了优化,只调用了一次,,在s5+s6返回时就调用拷贝构造函数
// 构造了s7
CMystring s7( s5 + s6 );
cout << &s7 << endl; // 就是在s5+s6返回时在外部构造的对象的地址
cout << "test end:" << endl;
cout << "------------------------4-------------------------------------------" << endl << endl;
CMystring str1("abc"),str2("123"), str3("");
cout << "test again:" << endl;
str3 = str1 + str2; // 调用一次拷贝构造函数 并不是因为有str3才会调用拷贝构造函数,str1+str2也会调用
cout << "= end" << endl;
CMystring str4 (str3); // 又调用一次拷贝构造函数
cout << "str3 addr:" << &str3 << " " << "str4 addr:" << &str4 << endl;
cout << "test again end:" << endl;
system("pause");
return 1;
}