C++空类和string类
1. 空类
1.1 空类默认哪六个成员函数。
1 class Empty
2 {
3 public:
4 Empty(); //缺省构造函数 Empty e;
5 Empty( const Empty& ); //拷贝构造函数 Empty e2(e1);
6 ~Empty(); //析构函数
7 Empty& operator=( const Empty& ); //赋值运算符 Empty e2 = e1;
8 Empty* operator&(); //取址运算符 &e
9 const Empty* operator&() const; //取址运算符const &e
10 };
1.2 空类的sizeof()=1
每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址。
2. string类
以下四个函数,是C++编译器会自动加入的四个函数。
1 class MyString 2 { 3 public: 4 MyString(const char *str = NULL);//默认参数,不传递的该参数的时候发挥作用。 5 MyString(const MyString &other); 6 MyString& operator=(const MyString &other); 7 ~MyString(); 8 private: 9 char *m_data; 10 }; 11 MyString::~MyString() 12 { 13 delete [] m_data; 14 } 15 MyString::MyString(const char *str) 16 { 17 if(NULL == str) 18 { cout<<"调用普通构造函数1"<<endl; 19 m_data = new char[1]; 20 *m_data = '\0'; 21 } 22 else 23 { 24 cout<<"调用普通构造函数2"<<endl; 25 size_t length = strlen(str); 26 m_data = new char[length+1]; 27 strcpy(m_data,str); 28 } 29 } 30 MyString::MyString(const MyString &other) 31 { cout<<"调用拷贝构造函数"<<endl; 32 size_t length = strlen(other.m_data); 33 m_data = new char[length+1]; 34 strcpy(m_data,other.m_data); 35 } 36 MyString& MyString::operator =(const MyString &other) 37 { 38 cout<<"调用赋值函数"<<endl; 39 //检查自赋值 40 if(this == &other) 41 return *this; 42 //释放原有的内存资源 43 delete [] m_data; 44 int length = strlen(other.m_data); 45 m_data = new char[length+1]; 46 strcpy(m_data,other.m_data); 47 return *this; 48 } 49 int _tmain(int argc, _TCHAR* argv[]) 50 { 51 MyString s0;//"调用普通构造函数1" 52 MyString s1 = "hi";//"调用普通构造函数2" 53 MyString s2("hi");//"调用普通构造函数2" 54 55 MyString s3 = s1;//"调用拷贝构造函数"上述实现为深拷贝。 56 MyString s4(s2);//"调用拷贝构造函数" 57 s4 = "hello!";//将"hello!"传入赋值函数形参时,要调用普通构造函数2;接着调用赋值函数。 58 s4 = s3;//"调用赋值函数" 59 return 0; 60 }
总结:仅定义对象或者传递对象的时候调用构造函数。
说明:拷贝构造函数必须传引用。调用拷贝构造函数如果传值,编译器会新开辟一段栈内存,建立此对象的临时拷贝,而建立临时拷贝又需要值传递调用拷贝构造函数,如此
进入死循环,直至内存耗尽死机。而传引用则无需新开辟内存空间,无需调用构造函数,形参对象只是另一个对象的别名。