概念部分:
(一)OOP思想四大属性:
1、封装
2、继承
3、多态
4、抽象
(二)权限:public private
(三)this指针:
成员方法声明或者调用的时候加上this指针
成员方法调用的时候,自动传参this指针
在成员方法内使用成员变量的地方,加上this指针的解引用
(四)构造函数:
初始化对象的时候自动调用的成员方法
如果不自己实现构造函数,编译器就会默认生成一个默认构造函数
如果自己实现,编译器就不会再生成
构造函数可以重载
(五)拷贝函数:
用一个已经存在的对象,构造相同类型的新对象
如果不自己实现该函数,编译器就会默认生成一个浅拷贝的拷贝构造
注意:
1、防止浅拷贝
2、拷贝构造必须传引用
(六)等号运算符重载函数:
用一个已经存在的对象给另外一个已经存在的对象进行赋值
如果不自己实现,编译器就会生成一个浅拷贝的等号运算符重载函数
注意:
1、防止自赋值
2、防止内存泄漏
3、防止浅拷贝
(七)析构函数:
一个对象的生存周期满后,自动调用的成员方法
如果不自己实现,编译器就会默认生成
析构函数没有参数,不可以重载
注意:
1、防止内存泄漏
代码演示:
#include <iostream>
#include <assert.h>
using namespace std;
class CGoods
{
private:
char* _name;
int _num;
double _price;
public:
//构造函数(注意在公共变量里面)
//函数名和类名相同
CGoods(const char* name = NULL, int num = 10, double price = 1.5)
{
cout << "构造函数" <<endl;
if(name != NULL)
{
_name = new char[strlen(name) + 1];
strcpy_s(_name, strlen(name)+ 1, name);
}
else
{
name = NULL;
}
_num = num;
_price = price;
}
//拷贝构造函数
//函数名和类名相同
CGoods(const CGoods& goods)
{
cout << "拷贝构造" <<endl;
_name = new char[strlen(goods._name)+ 1] ;
strcpy_s(_name, strlen(goods._name) + 1, goods._name);
_num = goods._num;
_price = goods._price;
}
//等号运算符重载函数
//函数名和类名相同
CGoods &operator = (const CGoods goods)
{
cout << "等号运算符重载函数"<<endl;
//防止自赋值
if(this == &goods)
return *this;
//防止内存泄漏
if(_name != NULL)
delete []_name;
//防止浅拷贝
_name = new char[strlen(goods._name) + 1];
strcpy_s(_name, strlen(goods._name) + 1, goods._name);
_num = goods._num;
_price = goods._price;
return *this;
}
//析构函数(在一个对象的生命周期结束后,清除它所引用的外部资源)
//先构造的后析构,先析构后构造的
~CGoods()
{
cout << "析构函数"<<endl;
delete []_name;
_name = NULL;
}
//打印函数
void show()
{
cout << "打印函数" << endl;
cout << "_name = " << _name << endl;
cout << "_num = " <<_num <<endl;
cout << "_pric = " <<_price <<endl;
}
};
CGoods fun1(CGoods good)
{
CGoods goods1 = good;
return good;
}
CGoods fun2(CGoods& good)
{
return "jidan";
}
int main()
{
CGoods good1("面包",10, 2);//构造good1
good1.show();
CGoods good2(good1);//拷贝构造good2
good2.show();
CGoods good3 = good2;//用good2拷贝构造good3
good3.show();
good3 = good1;//用good2给good3赋值(调用等号运算符重载函数)
good3.show();
CGoods good4("xaing chang");//构造good4
CGoods good5 = "la tioa";
/*
1:用char*先构造一个临时对象(非常量对象)
2:用临时对象拷贝构造good5
3:析构临时对象
系统会将以上的三个步骤优化成直接构造
*/
CGoods &ga =(CGoods)"fang bian mian";
/*
1:先构造一个临时对象(常量对象),该对象被ga引用
2:临时对象一旦被析构,他的生存周期就和引用相同(意思是说,为了引用而构造的临时对象的生命周期会被延长)
这个过程系统不给予优化
临时对象:
如果临时对象为标准类型(内置类型),则产生一个常值临时量
如果临时对象的类型为自定义类型分为两种情况:
1、隐式:出现类型名-》产生临时常量对象
eg:CGoods &a =(CGoods)"fang bian mian";
2、显式:未出现类型名-》产生临时非常量对象
eg:CGoods &ga ="fang bian mian";
*/
/* int &a = (int)10;//error(不允许泄露常量的引用或者指针给非常量的引用或者指针)
const int &a = (int)10;//true
int &b = 20;//error
const int &b = 20;//true
*/
good5 = fun1(good1);//先用good1拷贝构造参数good
/*
CGoods fun1(CGoods good)
{
CGoods goods1 = good;
return "jidan";
}
1:用good1拷贝构造参数good
2:用good拷贝构造goods1
3:用"jidan"构造临时对象
4:临时对象给good5赋值
5:析构临时对象
6:析构goods1
7:析构goods
*/
CGoods good6(fun2(good1));
/*
CGoods fun2(CGoods& good)
{
return "jidan";
}
1:构造临时常量
2:拷贝构造good6
3:析构临时对象
优化为:直接构造
*/
return 0;
}