类和对象
- 对象是具体的事物,而类则是从对象中抽象而来的。
- 类的定义包含数据成员和成员函数两部分;
- 类的访问限定符(public、private、protected)
- 对象的实例化:从栈实例化对象、从堆实例化对象
//从栈实例化对象
TV tv;
TV tv[20];
//从堆中实例化对象
TV *P = new TV();
TV *q = new TV[20];
delete p;
delete []q;
p=NULL;
q=NULL;
- 对象成员访问:
//从栈实例化的对象如何访问
int main(void)
{
TV tv;
tv.type = 0;
tv.changeVol();
return 0;
}
//从堆实例化的对象如何访问
int main(void)
{
TV *p = new TV();
p->type = 0;
p->chanageVol();
delete p;
p= NULL;
return 0;
}
C++属性封装
面向对象的基本思想就是要以对象为中心,具体来说就是要以谁做什么来表达程序的逻辑,体现到代码层面就是将所有的数据操作转化为成员函数的调用。
//举例,定义一个学生类
class Student
{
public:
void setAge(int _age){age=_age;}
int getAge(){return age;}
private:
string name;
int age;
......
};
类外定义
- 类内定义与内联函数:
内联函数:用关键字inline来定义
类内定义:将成员函数的函数体定义在类的内部,就称为类内定义。
类内定义的成员函数,编译器会将其优先编译为内联函数,对于复杂的函数来说,无法编译成内联函数的才会编译成普通的函数 - 类外定义:
- 同文件类外定义
成员函数虽然定义在类的外面,但是其定义与类的定义在同一个文件当中
//例子,有一个Car.cpp
class Car
{
public:
void run();
void stop();
void changeSpeed();
};
void Car::run(){}
void Car::stop(){}
void Car::changeSpeed(){}
- 分文件类外定义
分文件类外定义的时候需要先定义一个.h文件,也叫作头文件,类名和文件名建议写成一致。
//例子Car.h
class Car
{
public:
void run();
void stop();
void changeSpeed();
};
//在写一个文件Car.cpp
#include "Car.h"
void Car::run(){}
void Car::stop(){}
void Car::changeSpeed(){}
构造函数和析构函数
- 内存分区:
- 栈区:定义一个变量,内存由系统来控制
int x = 0; int *p = NULL;
- 堆区:堆区的内存需要程序员自己操作和管理
int *p = new int[20];
- 全局区:存储全局变量及静态变量
- 常量区:
string str = "hell0";
- 代码区:存储逻辑代码的二进制
- 对象的初始化:
- 有且仅有一次(重点)
- 根据条件来初始化
为了避免在初始化函数时的误操作,例如忘记调用了初始化函数或者是重复调用了初始化函数,从而推出了构造函数。
构造函数:
- 构造函数在对象实例化时被自动调用,且仅调用一次,通常只要将初始化的代码写在构造函数内即可。
- 构造函数与类同名
- 构造函数没有返回值(连void都不需要)
- 构造函数可以有多个重载形式
- 实例化对象时仅用到一个构造函数
- 当用户没有定义构造函数时,编译器自动生成一个构造函数
默认构造函数
在实例化对象时不需要传递参数的构造函数就称为默认构造函数。
class Student
{
public:
//下面是两种默认构造函数的举例子
Student(){}
Student(string name="Jim"){}
private:
string m_strName;
};
构造函数初始化列表
- 初始化列表
//初始化列表的例子
class Student
{
public:
Student():m_strName("Jim"),m_iAge(10){} //初始化列表
private:
string m_strName;
int m_iAgel;
};
- 初始化列表特性:
- 初始化列表先于构造函数执行
- 初始化列表只能用于构造函数
- 初始化列表可以同时初始化多个数据成员
拷贝构造函数
定义格式:类名(const类名&变量名)
拷贝构造函数的参数是确定的,不能重载
//例子
class Student
{
public:
Student(){m_strName = "jim";}
Student(const Student &stu){} //拷贝构造函数,传入的是一个引用
private:
string m_strName;
};
- 如果没有自定义的拷贝构造函数则系统系统自动生成一个默认的拷贝构造函数
- 当采用直接初始化或复制初始化实例化对象时系统自动调用拷贝构造函数。
析构函数:
在对象销毁时会被自动调用,完成的任务是归还系统的资源。
定义格式:~类名()
注:析构函数不允许加任何参数
特性:
- 如果没有自定义的析构函数则系统自动生成
- 析构函数在对象销毁时自动调用
- 析构函数没有返回值,没有参数也不能重载
对象的生命历程:
- 向操作系统申请内存
- 初始化列表
- 构造函数
- 参与运算
- 析构函数
- 释放内存