C++三大特征 封装 继承 多态
封装
类中的三个访问限定符
1.public 公有 任意位置
2.private 私有 本类类中
3.protected 保护 本类和子类
类中
默认以inline处理
类外
默认以普通的函数处理方式处理
this 类类型* const
构造函数
构造函数和类名相同
(1)作用:给类的实例化对象赋资源
(2)开辟内存、生成对象
(3)构造函数可重载
(4)构造函数不可手动调用、由系统调用
(5)构造函数为顺序构造
CGoods(char* name, int amount, float price)
{
std::cout << this << " :CGoods::CGoods(char*,int,float)" << std::endl;
mname = new char[strlen(name) + 1];
strcpy(mname, name);
mamount = amount;
mprice = price;
}
析构函数
(1)释放内存,销毁对象
(2)析构函数原型只有一个
(3)析构函数不可重载
(4)析构函数可手动调用、退化成普通函数的调用
(5)先构造后析构
~CGoods()
{
std::cout << this << " :CGoods::~CGoods()" << std::endl;
delete[] mname;
mname = NULL;
}
拷贝构造函数
用一个已经存在的对象来生成相同类型的新对象
1.形参一定要是引用,否则会陷入无限递归
2.默认的拷贝构造函数是浅拷贝
类中有指针 考虑实现深拷贝
初始化和赋值的区别
初始化:创建一个新的对象,并且其初值来源于另一个已存在的对象。
int a; a=b;
赋值:在两个已经存在的对象间进行的。
int a=b;
赋值的时候调用重载的赋值运算符,初始化的时候调用拷贝构造函数。
CGoods good3 = good2;
CGoods(CGoods src) 是拷贝构造函数,用同类型已经存在的对象构造新对象
CGoods src = good2;(3)--> CGoods(CGoods src)
CGoods src = good2;(4)--> CGoods(CGoods src)
good3 的产生调用了 CGoods(CGoods src) 函数,函数的调用先压实参,good2 是实参,src 是形参,实参到形参是初始化的过程(3),good2 是一个已存在的对象,若想生成新的对象要调用拷贝构造函数,调用函数第一件事是构造形参(4)
//CGoods good3 = good2;//初始化//系统默认使用拷贝构造函数
//对象自己的成员,可以任意访问自己的其他任何访问限定成员方法和成员变量
//CGoods(CGoods* const this, const CGoods &rhs)
CGoods(const CGoods &rhs)
{
cout << &rhs << "->" << this <<endl;
cout << "CGoods(const CGoods&)"<<endl;
mname = new char[strlen(rhs.mname)+1];
mamount = rhs.mamount;
mprice = rhs.mprice;
}
赋值运算符的重载函数
用一个已存在的对象来给另一个相同类型的已存在对象赋值
返回值是类类型的的引用,形参一定要用常引用
常引用作用:
1、防止实参被修改
2、接收隐士生成的临时对象
默认的赋值运算符的重载函数是浅拷贝
取地址操作符的重载函数
const 修饰的取地址操作符的重载函数
rhs 可以不加引用,用值传递,但是效率不高,因为会产生新的对象
不加引用时初始化的时候调用拷贝构造函数,产生新的 CGoods 对象
void operator=(const CGoods &rhs)
{
cout << &rhs << "->" << this <<endl;
cout << "operator=(const CGoods&)"<<endl;
//防止自赋值
if(this == &rhs)
{
return ;
}
//释放当前对象占用的其他资源
delete []mname;
mname = NULL;
//开辟新资源
mname = new char[strlen(rhs.mname)+1];
strcpy(mname, rhs.mname);
mamount = rhs.mamount;
mprice = rhs.mprice;
}
取地址操作符的重载函数
const 修饰的取地址操作符的重载函数
#include <iostream>
using namespace std;
class CGoods
{
public:
CGoods()
{
std::cout << this << " :CGoods::CGoods()" << std::endl;
mname = new char[1];
mname = '\0';
mamount = 0;
mprice = 0.0;
}
CGoods(char* name, int amount, float price)
{
std::cout << this << " :CGoods::CGoods(char*,int,float)" << std::endl;
mname = new char[strlen(name) + 1];
strcpy(mname, name);
mamount = amount;
mprice = price;
}
//CGoods good3 = good2;
//对象自己的成员,可以任意访问自己的其他任何访问限定成员方法和成员变量
//CGoods(CGoods* const this, const CGoods &rhs)
CGoods(const CGoods &rhs)
{
cout << &rhs << "->" << this <<endl;
cout << "CGoods(const CGoods&)"<<endl;
mname = new char[strlen(rhs.mname)+1];
strcpy(mname, rhs.mname);
mamount = rhs.mamount;
mprice = rhs.mprice;
}
//可以不加引用,用值传递,但是效率不高,因为会产生新的对象
//不加引用时初始化的时候调用拷贝构造函数,产生新的CGoods对象
void operator=(const CGoods &rhs)
{
cout << &rhs << "->" << this <<endl;
cout << "operator=(const CGoods&)"<<endl;
//防止自赋值
if(this == &rhs)
{
return ;
}
//释放当前对象占用的其他资源
delete []mname;
mname = NULL;
mname = new char[strlen(rhs.mname)+1];
strcpy(mname, rhs.mname);
mamount = rhs.mamount;
mprice = rhs.mprice;
}
~CGoods()
{
std::cout << this << " :CGoods::~CGoods()" << std::endl;
delete[] mname;
mname = NULL;
}
void show()
{
cout << "name:"<<mname<<endl;
cout << "amount:"<<mamount<<endl;
cout << "price:"<<mprice<<endl;
}
private:
char* mname;
int mamount;
float mprice;
};
int main()
{
CGoods good1;
CGoods good2("aaa",10,2.2);
CGoods good3 = good2;//初始化//系统默认使用拷贝构造函数
//默认的赋值,没有产生新的对象 发生浅拷贝问题,内存泄漏
//good.=(good3); good1调用'='传入good3
//void operator=(const CGoods &rhs)
good1 = good3;
}
class String
{
public:
String();
String(char* str);
String(const String& rhs);
String &operator=(const String&rhs);
~String();
private:
char* _str;
};
String::String()
{
_str=new char[1];
}
String::String(char* str)
{
int len=strlen(str);
_str=new char[len+1];
strcpy(_str,str);
}
String::String(const String& rhs)
{
int len=strlen(rhs._str);
_str=new char[len+1];
strcpy(_str,rhs._str);
}
String &String::operator=(const String&rhs)
{
if(this!=&rhs)
{
delete[] _str;
_str=new char[strlen(rhs._str)+1];
strcpy(_str,rhs._str);
}
return *this;
}
String::~String()
{
delete[] _str;
_str=NULL;
}```