this指针的特性:
1)this指针的类型是一个类类型 * const, 这表示什么呢?this指针的指向不能被改变。
2)this指针本身不占用大小,它并不是对象的一部分,在使用sizeof时候 不算长度。
3)this指针是类成员函数的第一个默认隐含参数,并不需要显示的输入,系统默认隐藏。
4)只有在类的非静态成员函数中调用,其他任何函数都不可以。
//因为静态成员属于类的,而不属于某个特定的对象。一个对象有属于自己的this指针,但是属于类的静态成员是没有this指针的。
5) thiscall调用约定:
a、参数从右向左压栈。
b、如果参数个数确定,this指针通过ecx传递给被调用者;如果参数不确定,this
指针在所有参数被压栈后压入堆栈。
c、对参数个数不定的,调用者清理堆栈,否则函数自己清理堆栈
6)this指针不能再初始化列表之中使用,在初始化列表之中,类的对象还没有创建,编译器不知道对象的结构就不知道 分配多大的空间。
一、构造函数
2、没有返回值。
3、有初始化列表(可以不用)。
4、新对象被创建,由编译器自动调用,且在对象的生命期内仅调用一次。
5、构造函数可以重载,实参决定了调用那个构造函数。
6、如果没有显示定义时,编译器会提供一个默认的构造函数。
7、无参构造函数和带有缺省值得构造函数都认为是缺省构造函数,并且缺省构造函数只能有一个。
8、构造函数不能用const来修饰,因为构造函数要改变参数的内容。
再来看一下构造函数的特性:
首先构造函数允许重载, 最为常见的构造函数的重载就是我们所熟知的拷贝构造函数。不但如此,你也可以显示的定义你的构造函数,如:Date(){} 里面可以什么也不写,这就是一个最简单的构造函数(什么也不写的构造还函数,你可以去看汇编代码,还是做了些事情的),只要你满足重载的条件(不过要注意 会不会产生二义性),你可以定义多个构造函数(通过参数可以选出你所要调用的构造函数)。当然如果你什么也没有写,那么编译器就会帮你自动生成一个构造函 数,当然这个构造函数也不会帮你做什么。
构造函数有两种缺省构造函数:
1.无参数的缺省构造函数。参数列表中什么都没有。
2.全缺省构造函数。参数列表中的参数都给一个默认值
但这两种缺省函数只能明确的显示一个,这样,当你再给一个空参数的情况下,两个函数都可以调用。不知道具体调用哪一个了。
【初始化列表】
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个数据
成员后面跟一个放在园括号中的初始化式。
【初始化顺序】
1、每个成员在初始化列表中只能出现一次。并不能对一个变量初始化两次。
2、初始化列表仅用于初始化数据成员,并不指定这些数据成员的初始化顺序,
数据成员在类中定义顺序就是在参数列表中的初始化顺序。
3、尽量避免使用成员初始化成员,成员的初始化顺序最好和成员的定义顺序保持一致。
以下几种情况时必须使用初始化列表
1.常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面
2.引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面
3.没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化
构造函数的作用:
1)构造对象
2)初始化对象
3)类型转化(必须是单参)
默认构造函数
当你没有显示定义一个构造函数的时候。编译器会帮你自动定义一个构造函数。不过这个构造函数什么都不做。但是如果你显示的定义了一个构造函数,即使这个构造函数什么都不做,编译器也不会自动定义默认构造函数。
二、拷贝构造函数 Data(const Data& d)
1、对象实例化对象
CDate d1(1990, 1, 1);
CDate d2(d1);
2、传值方式作为函数的参数
void FunTest(const CDate date)
{}
3、传值方式作为函数返回值
CDate FunTest()
{
CDate date;
return date;
}
三、析构函数
析构函数:与构造函数功能相反,在对象被销毁时,由编译器自动调用,完成类的一些资源清理和汕尾工作。在使用析构函数的时候,顺序是先进后出,后面运行的先析构。
class CArray
{
public:
CArray(size_t capacity)
: _capacity(capacity)
{
_pData = ( int*)malloc(capacity*sizeof (int));
_size = 0;
}
~CArray()
{
if (NULL != _pData)
{
free(_pData);
_pData = NULL;
}
_size = 0;
_capacity = 0;
}
private:
int* _pData;
size_t _size;
size_t _capacity;
};
构函数的特点:
1)一个类里面只有一个,对象被销毁的时候只调用一次。
2)不能有参数,也不能有返回值,因此析构函数不能重载
3)如果没有显示的给出,编译器会默认生成一个。
4)在对象生命周期结束的时候,由编译器自动调用。
5)析构函数在函数体内并不是删除对象,而是做一些清理工作。
四、运算符的重载(后三个默认函数)
在这里提到了运算符重载,于是我把后面的三个重载放在一起讲。先来了解一下什么叫做运算符重载(或者叫做操作符重载),重载操作符是具有特殊函数名的函 数,关键字operator后面接需要定义的操作符符号。操作符重载也是一个函数,具有返回值和形参表。它的形参数目与操作符的操作数目相同,函数调用操 作符可以接受任意数目的操作数。
可以被重载的操作符:
不可以被重载的操作符:
1、不能通过连接其他符号来创建新的操作符:比如operator@;
void operator @(){}
2、重载操作符必须有一个类类型或者枚举类型的操作数
1
2
3
4
5
6
7
8
9
10
|
1
.
int
operator +(
const
int
_iNum1 ,
const
int
_iNum2 )
// 报错
2
. {
3
.
return
( _iNum1 + _iNum2);
4
. }
5
.
6
. typedef
enum
TEST {one ,two ,three };
7
.
int
operator+(
const
int
_iNum1 ,
const
TEST _test )
8
. {
9
.
return
_iNum1;
10
. }
|
4、重载前后操作符的优先级和结合性是不变的
5、不在具备短求值特性重载操作符不能保证操作符的求值顺序,在重载&&和||中,对每个操作数
都要进行求值,而且对操作数的求值顺序不能做规定,因此:重载&&、 ||和逗号操作符不是好的做法。
6、作为类成员的重载函数,其形参看起来比操作数数目少1成员函数的操作符有一个默认的形参this,限定为第一个形参。
1
2
3
4
5
6
7
8
9
|
CTest operator+(
const
CTest test1,
const
CTest test2)
const
// 报错
{
return
test1;
}
CTest operator+(
const
CTest test1)
const
{
return
test1;
}
|
8、操作符定义为非类的成员函数时,一般将其定义为类的友元
9、== 和 != 操作符一般要成对重载
10、下标操作符[]:一个非const成员并返回引用,一个是const成员并返回引用
11、解引用操作符*和->操作符,不显示任何参数
13、自增自减操作符
前置式++/--必须返回被增量或者减量的引用
后缀式操作符必须返回旧值,并且应该是值返回而不是引用返回
14、输入操作符>>和输出操作符<<必须定义为类的友元函数
Complex::Complex( double real=0.0 , double image=0.0)
{
_dReal = real;
_dImage = image;
}
Complex::Complex(const Complex& complex)
{
_dReal = complex._dReal;
_dImage = complex._dImage;
}
Complex&Complex:: operator=(const Complex& complex)
{
if (this != &complex)
{
_dReal = complex._dReal;
_dImage = complex._dImage;
}
return *this;
}
Complex Complex:: operator+(const Complex& complex)
{
Complex ret(_dReal + complex._dReal, _dImage + complex._dImage);
return ret;
}
Complex Complex:: operator-(const Complex& complex)
{
Complex ret(_dReal - complex._dReal, _dImage - complex._dImage);
return ret;
}
Complex Complex:: operator*(const Complex& complex)
{
Complex ret(_dReal*complex._dReal - _dImage*complex._dImage, _dReal*complex._dImage + _dImage*complex._dReal);
return ret;
}
Complex Complex::operator/(const Complex& complex)
{
Complex ret((_dReal * complex._dReal + _dImage * complex._dImage) / (complex._dReal * complex._dReal + complex._dImage * complex._dImage),
(complex._dReal * _dImage - _dReal * complex._dImage) / (complex._dReal * complex._dReal + complex._dImage * complex._dImage));
return ret;
}
Complex& Complex::operator+=(const Complex& complex)
{
_dReal += complex._dReal;
_dImage += complex._dImage;
return *this;
}
Complex& Complex::operator+=(const Complex& complex)
{
_dReal -= complex._dReal;
_dImage -= complex._dImage;
return *this;
}
Complex& Complex::operator*=(const Complex& complex)
{
double temp = 0.0;
temp = _dReal;
_dReal = (_dReal*complex._dReal - _dImage *complex._dImage);
_dImage = (temp * complex._dImage + _dImage * complex._dReal);
return *this;
}
Complex& Complex::operator/=(const Complex& complex)
{
double temp = 0.0;
temp =_dReal;
_dReal = (_dReal * complex._dReal + _dImage * complex._dImage) / (complex._dReal * complex._dReal + complex._dImage * complex._dImage);
_dImage = (complex._dReal * _dImage - temp * complex._dImage) / (complex._dReal * complex._dReal + complex._dImage * complex._dImage);
return *this;
}
bool Complex:: operator >(const Complex& complex)
{
bool flag;
double num1 = _dReal * _dReal + _dImage * _dImage;
double num2 = complex._dReal * complex._dReal + complex._dImage * complex._dImage;
if (num1 > num2)
{
flag = true;
}
else
{
flag = false;
}
return flag;
}
bool Complex:: operator >=(const Complex& complex)
{
bool flag;
double a = _dReal * _dReal + _dImage * _dImage;
double b = complex._dReal * complex._dReal + complex._dImage * complex._dImage;
if (a >= b)
{
flag = true;
}
else
{
flag = false;
}
return flag;
}
bool Complex:: operator <(const Complex& complex)
{
bool flag;
double a = _dReal * _dReal + _dImage * _dImage;
double b = complex._dReal * complex._dReal + complex._dImage * complex._dImage;
if (a < b)
{
flag = true;
}
else
{
flag = false;
}
return flag;
}
bool Complex::operator <=(const Complex& complex)
{
bool flag;
double a = _dReal * _dReal + _dImage * _dImage;
double b = complex._dReal * complex._dReal + complex._dImage * complex._dImage;
if (a <= b)
{
flag = true;
}
else
{
flag = false;
}
return flag;
}
bool Complex:: operator ==(const Complex& complex)
{
bool flag;
double a = _dReal * _dReal + _dImage * _dImage;
double b = complex._dReal * complex._dReal + complex._dImage * complex._dImage;
if (a == b)
{
flag = true;
}
else
{
flag = false;
}
return flag;
}
bool Complex:: operator !=(const Complex& complex)
{
bool flag;
double a = _dReal * _dReal + _dImage * _dImage;
double b = complex._dReal * complex._dReal + complex._dImage * complex._dImage;
if (a != b)
{
flag = true;
}
else
{
flag = false;
}
return flag;
}
用的是C++编译器