面向对象、c++类的默认成员函数

面向对象是什么?

面向对象:是一种程序设计范型,同时也是一种程序开发的方法。
对象指的是类的实例,将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。

这里写图片描述

面向对象的三大特性:
通过一幅图来形象的了解一下面向对象
注:图来源于网络

这里写图片描述

  • 封装:
    就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

  • 继承:
    面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
    通过继承创建的新类称为“子类”或“派生类”。
    被继承的类称为“基类”、“父类”或“超类”。

  • 多态:
    是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。


类的四个默认成员函数

在了解默认成员函数之前,需要了解一下什么是this 指针

隐含的this指针

  • this指针从本质上来说是一个函数参数,这个函数参数是编译器自动为我们添加的,所以每一个对象都能通过 this 指针来访问自己的地址
  • this 指针是所有成员函数的隐含参数。
  • 注意,因为this指针是编译器自动添加的,所以我们不能在成员函数的形参中添加this指针的参数定义,也不能在调用时显示传递对象的地址给this指针

    汇编更清楚

这里写图片描述

类的默认成员

1.【构造函数】
类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。

构造函数的特征如下:

  • 函数名与类名相同。
  • 无返回值。
  • 对象构造(对象实例化)时系统自动调用对应的构造函数。
  • 构造函数可以重载。
  • 构造函数可以在类中定义,也可以在类外定义。
  • 如果类定义中没有给出构造函数,则C++编译器自动产生一个缺省的构造函数,但只要我们定义了一个构造函数,系统就不会自动
    生成缺省的构造函数。
  • 无参的构造函数和全缺省值的构造函数都认为是缺省构造函数,并且缺省的构造函数只能有一个。

  • 无参构造函数&带参的构造函数

class Date
{
public :
// 1.无参构造函数
Date ()
{}
// 2.带参构造函数
Date (int year, int month , int day )
{
_year = year ;
_month = month ;
_day = day ;
}
private :
int _year ;
int _month ;
int _day ;
};
void TestDate1 ()
{
Date d1 ; // 调用无参构造函数
Date d2 (2015, 1, 1); // 调用带参的构造函数
Date d3 (); // 注意这里没有调用d3的构造函数定义出 d3
  • 带缺省参数的构造函数
class Date
{
public :
// 3.缺省参数的构造函数
Date (int year = 2000, int month = 1, int day = 1)
{
_year = year ;
_month = month ;
_day = day ;
}
// 4.半缺省参数的构造函数(不常用)
Date (int year, int month = 1)
{
_year = year ;
_month = month ;
_day = 1;
}
private :
int _year ;
int _month ;
int _day ;
};
void Test()
{
Date d1 ; // 调用缺省构造函数
Date d2 (2015, 1, 9); // 调用缺省构造函数
}

2、【拷贝构造】
创建对象时使用同类对象来进行初始化,这时所用的构造函数称为拷贝构造函数(Copy Constructor),拷贝构造函数是特殊的构造函数。

特征:
1. 拷贝构造函数其实是一个构造函数的重载。
2. 拷贝构造函数的参数必须使用引用传参,使用传值方式会引发无穷递归调用。(思考为什么?)
3. 若未显示定义,系统会默认缺省的拷贝构造函数。缺省的拷贝构造函数会,依次拷贝类成员进行初始化。

class Date
{
public :
Date()
{}
// 拷贝构造函数
Date (const Date& d)
{
_year = d ._year;
_month = d ._month;
_day = d ._day;
}
private :
int _year ;
int _month ;
int _day ;
};
void TestDate1 ()
{
Date d1 ;
// 下面两种用法都是调用拷贝构造函数,是等价的。
Date d2 (d1); // 调用拷贝构造函数
Date d3 = d1; // 调用拷贝构造函数
}

3.【析构函数】
当一个对象的生命周期结束时,C++编译系统会自动调用一个成员函数,这个特殊的成员函数即析构函数。
构造函数是特殊的成员函数,其特征如下:
1. 析构函数在类名加上字符~。
2. 析构函数无参数无返回值。
3. 一个类有且只有一个析构函数。若未显示定义,系统会自动生成缺省的析构函数。
4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。
5. 注意析构函数体内并不是删除对象,而是做一些清理工作。

class Array
{
public :
Array (int size)
{
_ptr = (int *)malloc( size*sizeof (int));
}
// 这里的析构函数需要完成清(shi)理(fang)工(kong)作(jian)。
~ Array ()
{
if (_ptr )
{
free(_ptr );
_ptr = 0;
}
}
private :
int* _ptr ;
};

4、【运算符重载】
特征:
1. operator+合法的运算符构成函数名(重载<运算符的函数名:operator<)。
2. 重载运算符以后,不能改变运算符的优先级/结合性/操作数个数。

赋值运算符重载

Date& operator = (const Date& d)
{
// 这里的if条件判断是在检查d=d的情况(自己给自己赋值)
if (this != &d)
{
this->_year = d. _year;
this->_month = d. _month;
this->_day = d. _day;
}
return *this ;
void Test ()
{
Date d1 ;
Date d2 = d1; // 调用拷贝构造函数
Date d3 ;
d3 = d1 ; // 调用赋值运算符的重载
}

猜你喜欢

转载自blog.csdn.net/ddcodingya/article/details/79734706