目录
一 :什么是面向对象
1:引子
从这里开始,我们就算是真正开始接触C++语言,我们都说C语言与C++最大的区别是C是面向过程语言,而C++是面向对象语言,而C++中的类与对象就是为了实现面向对象而设计的。
2:什么是面向对象
相信大家在学习C++时有一个很大的问题就是什么是面向对象,通俗点讲,就是语序问题。
面向过程: 谓(主,宾)。面向对象:主 (谓,宾)。
比如说同样是我爱你,C语言注重的是爱这个动作的设计,而C++注重的是我,你这两个人的交互。这就是为什么我们常听,面向对象更符合人的思维。
再举个例子,比如说把大象关进冰箱这个问题。
C语言(面向过程)会怎么干这件事情?首先创建一个描述大象的结构体类型和一个描述冰箱的类型,再分别写出计算大象体重,打包大象,把大象放进冰箱,开冰箱门和关冰箱门等等函数去实现。
而C++(面向对象)会怎么干这件事情?首先创建一个大象类,把大象的特征和对大象的各种操作(方法)写在一起(封装),而对于冰箱也是一样。这样写的好处是,改明我不想把大象装进冰箱了,让其他动物装进去,由于其他动物与大象一样都是动物,具有很多相同点,可以让其他动物类型直接照搬大象的处理方法,而这种操作就叫做继承。会比面向过程减少很多冗余代码,增加开发效率。
二:类与对象
1:定义
说了大半天,现在我们请出今天的主角,上代码
class circle
{
public:
//内容
protected:
//内容
private:
//内容
};
创建一个类关键字是class,class+类名。
2:访问权限以及访问限定符
访问权限概念:控制哪些成员可以在类外直接被访问,哪些只能通过方法进行访问
访问限定符:
public(公有):可以在类以外的作用域被访问。
protected(保护):主要是在继承中与private有区别,初学可认为一样
private(私有):不能在类以外的访问。
之所以有这些概念,还是要说回封装,其实封装就是将数据与数据的操作方法结合起来。把数据隐藏起来,进对外开放方法接口与外界交互。而限定的符就是来实现这个功能的。
而这些操作方法我们称之为成员函数。
三:类的默认成员函数
C++语言之所以难以理解,就是在他的底层替你做了很多事情,但是这些都是默认调用。在一个空类中有六个默认的成员函数。
1:构造函数(初始化工作)
(1):作用
一个变量创建好后我们一般对其进行初始化,而类中数据也不例外,这时候编译器就会自动调用构造函数去完成初始化动作。
(2):构造函数
//构造函数
circle()
{
}
构造函数是特殊成员函数之一,名字与类名一样,在创建对象时就会被编译器自动调用,并且每个生命周期就调用一次。
(2)默认构造函数:
如果我们没定义构造函数,那么编译器也会有一个默认的构造函数,里面没有任何东西。一旦我们定义,自动覆盖默认构造函数。
(3)特征
1.构造函数名与类名一样。
2.构造函数无返回值类型。
3.创建对象时编译器自动调用。
4.构造函数是支持函数重载的。
5.无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。简而言之就是如果有多个构造函数,当作函数重载去理解就行了。而且注意的是,他们两个是可以同时存在的,但是使用的时候是不能够的,因为编译器认为他们都是没有参数的函数,会造成歧义。
注意:在调用没有参数的构造函数时不能加括号!!!
如图所示,在调用无参的构造函数不要加括号,否则就会报错。
2:析构函数(清理工作)
(1)作用
与构造函数相反,在对象销毁的时候自动调用析构函数完成对类的一些清理工作。
(2)析构函数
//析构函数
~test()
{
}
(3)特征
1.析构函数是~加上类名。
2.无参数无返回值,注意与构造函数区分。
3.一个类有且只有一个析构函数,不存在重载的情况。
4.编写者如果没有定义析构函数,编译器也会有一个默认的析构函数。
5.对象被销毁时,编译器自动调用析构函数。
(4)常用情景
在栈上开辟的内存会被系统自动回收,而malloc calloc realloc new这些有我们自己申请的内存就需要我们手动还给操作系统。这时候就体现了析构函数的作用。
#include<iostream>
using namespace std;
class test
{
public:
//构造函数
test(int x, int y)
{
m_x = x;
m_y = y;
name = (char*)malloc(100);
strcpy(name, "zhangsan");
}
void print()
{
cout << m_x << m_y << endl;
cout << name << endl;
}
//析构函数
~test()
{
if (name != NULL)
{
free(name);
cout << "succ" << endl;
}
}
private:
int m_x;
int m_y;
char* name;
};
void test1()
{
test t1(10,10);
t1.print();
}
int main()
{
test1();
return 0;
}
如果有多个对象实例化的时候会是什么情况,我们来看个例子
int main
{
test t1;
test t2;
}
这两个对象t1和t2肯定是t1先构造t2在构造,那么析构的顺序呢?
由于他们都是栈上创建的,所以先入栈的后出栈,由于t1先入栈所以后出栈,故而构造函数的顺序与析构函数的顺序是相反的。