C++类和对象
一:类和对象的基础知识,如类的定义,访问限定符,面向对象封装性,对象的大小计算等等。
对象大小的计算:与结构体计算方法相同 注 意:内部函数不参与大小计算 空的类大小唯一 编译器分配他一字节 目的是占位。
二:四个默认成员函数及运算符重载相关知识
1:析构函数
成员变量为私有的,要对它们进行初始化,必须用一个公有成员函数来进行。同时这个函数应该有且仅在定义对象时自动执行一次,这时调用的函数称为构造函数(constructor)。
构造函数是特殊的成员函数,其特征如下:
1:函数名与类名相同。
2:无返回值。
3:对象构造(对象实例化)时系统自动调用对应的构造函数。
4:构造函数可以重载。
5:构造函数可以在类中定义,也可以在类外定义。
6:如果类定义中没有给出构造函数,则C++编译器自动产生一个缺省的构造函数,但只要我们定义了一个构造函数,系统就不会自动生成缺省的构造函数。
7:无参的构造函数和全缺省值的构造函数都认为是缺省构造函数,并且缺省的构造函数只能有一个。
2:拷贝构造函数
创建对象时使用同类对象来进行初始化,这时所用的构造函数称为拷贝构造函数(Copy Constructor),拷贝构造函数是特殊的构造函数。
特征:
1. 拷贝构造函数其实是一个构造函数的重载。
2. 拷贝构造函数的参数必须使用引用传参,使用传值方式会引发无穷递归调用。(思考为什么?)
3. 若未显示定义,系统会默认缺省的拷贝构造函数。缺省的拷贝构造函数会,依次拷贝类成员进行初始化。
3:析构函数
当一个对象的生命周期结束时,C++编译系统会自动调用一个成员函数,这个特殊的成员函数即析构函数(destructor)
构造函数是特殊的成员函数,其特征如下:
1:析构函数在类名加上字符~。
2:析构函数无参数无返回值。
3:一个类有且只有一个析构函数。若未显示定义,系统会自动生成缺省的析构函数。
4:对象生命周期结束时,C++编译系统系统自动调用析构函数。
ps:注意析构函数体内并不是删除对象,而是做一些清理工作。
4:赋值运算符重载
拷贝构造函数是创建的对象,使用一个已有对象来初始化这个准备创建的对象。赋值运算符的重载是对一个已存在的对象进行拷贝赋值。
重载:
运算符重载特征:
operator+ 合法的运算符 构成函数名(重载<运算符的函数名:operator< )。
重载运算符以后,不能改变运算符的优先级/结合性/操作数个数。ps:5个C++不能重载的运算符: .*/::/sizeof/?:/.
运算符重载背后做的事情:
首先写一个 运算符重载的代码:
#include <iostream>
using namespace std;
class Data
{
public:
Data(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Display()
{
cout<<""<<_year<<"-"<<_month<<"-"<<_day<<endl;
}
void operator= (const Data&d)
{
if (this != &d)
{
this->_year = d._year;
this->_month = d._month;
this->_day = d._day;
}
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1(1993,8,3);
d1.Display();
Data d2(122,3,5);
d2 = d1;
d2.Display();
return 0;
}
运行代码情况如上:void operator = (const Data&d) 其实参数列表还包含了一个 默认的this指针,所以其实有两个参数
然后在主函数中,调用= 的时候,d1 = d2, 其实隐含是d1.operator = (&d1,d2)。经过改进 为了方便 只用写d1 = d2就行。
那段代码也可以写成是:
return this->_year = -year 又this指针默认指向第一个对象。
隐含的this指针:
1. 每个成员函数都有一个指针形参,它的名字是固定的,称为this指针,this指针是隐式的。(构造函数比较特殊,没有这个隐含this形参)
2. 编译器会对成员函数进行处理,在对象调用成员函数时,对象地址作实参传递给成员函数的第一个形参this指针。
3. this指针是成员函数隐含指针形参,是编译器自己处理的,我们不能在成员函数的形参中添加this指针的参数定义,也不能在调用时显示传递对象的地址给this指针。