C++:类和对象 - 指南
一、类和对象的定义
C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++
的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,它包含了数据表示法和用
于处理数据的方法。类中的数据和方法称为类的成员。函数在一个类中被称为类的成员。
打个比方说明一下什么是类,比如有一条小狗,小狗有名字叫旺财,旺财的年龄是 2 岁,
同时旺财会汪汪的叫,也能跑。我们统称狗这个为类,类是我们抽象出来的,因为狗不只有上
面的属性,还有体重,毛发的颜色等等,我们只抽象出几种属性成一个类。具体到哪条狗就叫
对象。
从类中实例化对象分两种方法,一种是从栈中实例化对象,一种是从堆中实例化对象。
类是创建对象的模板,一个类可以创建多个对象,每个对象都是类类型的一个变量;创建对象的过程也叫做类的实例化。
类的定义
class 类名{
public:
公有的数据;
protected:
保护的数据;
private:
私有的数据;};
C++通过 public、protected、private 三个关键字来控制成员变量和成员函数的访问权限,它们分别表示公有的、受保护的、私有的,被称为成员访问限定符。所谓访问权限,就是你能不能使用该类中的成员。
#include
using namespace std;
class Dog
{
public://不写关键字的时候默认是private属性
string name;
int age;
void run()
{
coutage = 3;
coutage<
二、构造函数和析构函数
定义了一个名称和类名相同,没有返回值的函数,这个函数称为构造函数。构造函数的特殊之处在于,它会在类实例化的时候被调用。
#include
class Dog
{
public:
Dog();
};
对象实例化的时候,会调用构造函数,而对象销毁的时候,就会调用析构函数。
对象销毁:程序结束了由系统释放;删除指针对象的时候
#include
class Dog
{
public:
~Dog();
};
举个栗子1:
#include
using namespace std;
class Dog
{
public:
Dog(){
cout<<"构造函数被执行了"<
举个栗子2:
#include
using namespace std;
class Dog
{
public:
Dog(){
cout<<"构造函数被执行了"<
栗子1输出: 栗子2输出:
构造函数被执行了 构造函数被执行了
析构函数被执行了
栗子1是从栈中实例化对象,程序结束了系统会回收对象
栗子2中析构函数没有执行,因为堆中实例化对象要用delete删除,栗子2中的对象没有被销毁
在类实例化对象的时候,如果没有定义构造函数,则编译器会合成一个默认的构造函数;当有了对象后,如果没有定义析构函数,则编译器会合成一个默认的析构函数。
三、this指针
this指针装着当前对象的地址,即每个对象都有自己的地址,我们可通过&t1,&t2...(对对象取地址)获取到各个对象的地址,C++在类内直接提供了地址,我们就不需要在类外获取了。C++面向对象编程提供了一个变量叫做this指针,该地址自动初始化成我们当前对象的地址,我们可以在类内直接使用this指针,就可使用当前对象的地址了。
这时候我们会想到,我直接取对象的地址,通过函数传递到类的内部去使用,为什么还存在this指针呢?这就是C++面向对象编程的思想了,对象表面是个变量,实际上它是区别于变量int、double等等,对象是拥有一个丰富功能的一个完整个体,一个对象自身就知道自己的地址,不需要“别人告诉”。
每个成员函数:析构、构造、自定义函数,都可以使用this指针,this指针作为函数的隐藏参数,传递给函数,每个成员都有,this的实现方法暂不研究。
this指针可用于区分类成员和局部变量
#include
using namespace std;
class Test
{
private:
//Test*this; "相当于类"内有this变量
int a;
public:
Test(/* Test*this ,*/int a)
{
this->a = a; //用处1:区分 类成员和函数参数的局部变量
}
void Print(){
cout<
this指针可用于以下栗子:
#include
using namespace std;
class Test
{
private:
//Test*this; "相当于类"内有this变量
int a;
public:
Test(/* Test*this ,*/int a)
{
//this->a = a; //用处1:区分 类成员和函数参数的局部变量
(*this).a = a;
}
void Print(){
cout<
四、类的继承
创建新类时,并不需要创建全新的数据和成员函数,我们可以指明这个新类继承现有类的成员。此时,现有的类称为“基类”,继承实现的新类称为“派生类”。
举个栗子:子类可以调用父类的成员
#include
using namespace std;
//基类/父类
class Animal
{
public:
string name;
int age;
void run()
{
cout<<"狗的年龄: "<
(1)公有继承时基类中各成员属性保持不变,基类中private成员被隐藏。派生类的成员只能访问基类中的public/protected成员,而不能访问private成员;派生类的对象只能访问基类中的public成员。 下面栗子对应派生类的成员不能访问private成员![]()
(2)保护继承时基类中各成员属性均变为protected,并且基类中private成员被隐藏。派生类的成员只能访问基类中的public/protected成员,而不能访问private成员;派生类的对象不能访问基类中的任何的成员。
![]()
(3)私有继承时基类中各成员属性均变为private,并且基类中private成员被隐藏。派生类的成员也只能访问基类中的public/protected成员,而不能访问private成员;派生类的对象不能访问基类中的任何的成员。
![]()
五、函数重载
在同一个作用域内,声明几个功能类似的同名函数,并且这些同名函数的参数个数、参数类型或者参数顺序不同,那么就叫函数重载。
栗子1:
#include
using namespace std;
class Dog
{
public:
Dog(int weight)//构造函数重载
{
cout<<"int 狗的体重:"<
栗子2:
#include
using namespace std;
class Dog{
public:
void getWeight(int weight){
cout<<"int 狗的体重:"<
学习更新行中·········