这篇博客记录了学习第一题时遇到的困惑和解决方法:
1. 为什么返回对象的引用?
参考 http://www.cnblogs.com/codingmengmeng/p/5871254.html
重载运算符返回void、返回对象本身、返回对象引用。返回对象引用基于下面两个原因:
a.允许进行连续赋值
b. 虽然返回对象也可以连续赋值,但是返回对象时要调用拷贝函数和析构函数导致不必要的开销,降低赋值运算符等的效率。
赋值运算符的本意为“返回左值的引用”。
举例解释返回对象和返回:
#include <iostream>
using namespace std;
class String
{
private:
char *str;
int len;
public:
String(const char* s);//构造函数声明
String operator=(const String& another);//运算符重载,此时返回的是对象
void show()
{
cout << "value = " << str << endl;
}
/*copy construct*/
String(const String& other)
{
len = other.len;
str = new char[len + 1];
strcpy(str, other.str);
cout << "copy construct" << endl;
}
~String()
{
delete[] str;
cout << "deconstruct" << endl;
}
};
String::String(const char* s)//构造函数定义
{
len = strlen(s);
str = new char[len + 1];
strcpy(str, s);
}
String String::operator=(const String &other)//运算符重载
{
if (this == &other)
return *this;
// return;
delete[] str;
len = other.len;
str = new char[len + 1];
strcpy(str, other.str);
return *this;
// return;
}
int main()
{
String str1("abc");
String str2("123");
String str3("456");
str1.show();
str2.show();
str3.show();
str3 = str1 = str2;//str3.operator=(str1.operator=str2)
str3.show();
str1.show();
getchar();
return 0;
}
赋值运算符返回的是类型本身, 输出结果如下:
value = abc
value = 123
value = 456
copy construct
copy construct
deconstruct
deconstruct
value = 123
value = 123
若改为: String&operator+(const String& str)
结果为:
value = abc
value = 123
value = 456
value = 123
value = 123
举例说明返回对象引用符合原始语义清晰:
(str3= str1) = str2;
一般来说,我们认为上式是将str1赋值给str3,然后str2的值再赋值给str3;
当返回的是对象的引用时:
#include <iostream>
using namespace std;
class String
{
private:
char *str;
int len;
public:
String(const char* s);//构造函数声明
String& operator=(const String& another);//运算符重载,此时返回为空
void show()
{
cout << "value = " << str << endl;
}
/*copy construct*/
String(const String& other)
{
len = other.len;
str = new char[len + 1];
strcpy(str, other.str);
cout << "copy construct" << endl;
}
~String()
{
delete[] str;
cout << "deconstruct" << endl;
}
};
String::String(const char* s)
{
len = strlen(s);
str = new char[len + 1];
strcpy(str, s);
}
String& String::operator=(const String &other)
{
if (this == &other)
return *this;
// return;
delete[] str;
len = other.len;
str = new char[len + 1];
strcpy(str, other.str);
return *this;
// return;
}
int main()
{
String str1("abc");
String str2("123");
String str3("456");
str1.show();
str2.show();
str3.show();
(str3 = str1) = str2;
cout << "str3的内容为:" << endl;
str3.show();
getchar();
return 0;
}
输出结果为:
value = abc
value = 123
value = 456
str3的内容为:
value = 123
当返回的是对象时:(改为String operator=(constString& another);)输出结果为:
value = abc
value = 123
value = 456
copy construct
copy construct
deconstruct
deconstruct
str3的内容为:
value = abc
原因:在执行(str3=str1)后,因为返回的是对象(一个临时对象,str3的一个拷贝),不是引用,str2是对一个临时对象赋值,使用str3的内容保持不变。
构造函数:
构造函数的名字与类名相同,但构造函数没有返回类型。
Sales_data()=default;//默认构造函数
Sales_data (const std::string &s) : bookNo(s){}//冒号以及冒号和花括号之间的代码,这部分称为构造函数初始值列表,它负责为新创建的对象的一个或几个数据成员赋初值
3.delete a 与delete [] a的区别:
a.针对简单类型 使用new分配后不管是数组还是非数组形式内存空间用这两种形式均可,例如:
int *a=new int[10];
delete a;
delete [] a;
原因是:分配简单类型内存时,内存大小已经确定,系统可以记忆并管理,在析构时,系统不会调用析构函数,它直接通过指针可以获取实际分配的内存空间
b.针对class,两种表达体现出具体差异
class A
{
private:
char* m_cBuffer;
int m_nlen;
public:
A(){m_cBuffer=newchar [m_nLen];}
~A(){delete []m_cBuffer;}
};
A * a=new A[10];
delete a;//仅释放了a指针指向的全部内存空间,也就是只调用了a[0]对象的析构函数,剩下的a[1]到a[9]自行分配到m_cBuffer对应内存空间将不能释放,从而造成内存泄漏
delete [] a;//调用使用类对象的析构函数释放用户自己分配内存空间并且释放了a指针指向的全部内存空间。
所以总结下就是,如果ptr代表一个用new申请的内存返回的内存空间地址,即所谓的指针,那么:
delete ptr 代表用来释放内存,且只用来释放ptr指向的内存。
delete[] rg 用来释放rg指向的内存,!!还逐一调用数组中每个对象的destructor!!
对于像int/char/long/int*/struct等等简单数据类型,由于对象没有destructor,所以用delete 和delete [] 是一样的!但是如果是C++对象数组就不同了。
举例学习:
#include<iostream>
using namespace std;
class Babe {
public:
Babe() {
cout << "Creatr a Babe to talk with me"<<endl;
}
~Babe() {
cout << "Babe do not go away,listen to me" << endl;
}
};
int main() {
Babe* pbabe = new Babe[3];
//delete pbabe;//会引发中断
//pbabe = new Babe[3];
delete [] pbabe;
getchar();
return 0;
}
Creatr a Babe to talk with me
Creatr a Babe to talk with me
Creatr a Babe to talk with me
Babe do not go away,listen to me
Creatr a Babe to talk with me
Creatr a Babe to talk with me
Creatr a Babe to talk with me
Babe do not go away,listen to me
Babe do not go away,listen to me
Babe do not go away,listen to me