欢迎光临
我们一直在努力

C++入门基础(5):类与对象

在前面四节中,我们已经熟悉了 C++ 的过程性语言,而在这一节我们将真正接触 C++ 面向对象的语言。

目录

介绍

基础机制

公有、保护与私有成员

构造函数和析构函数

继承

虚基类

介绍

类,可以理解成一个种类。对象,可以理解成属于这一个种类的个体。例如,我们可以创建一个载具类,然后再使用这个载具类去定义一个对象 car。

class Vehicle{
……
}
Vehicle car;

当然,我们光定义一个类是没有实际意义的,我们还需要去描述这个类。

继续延用上文 car 的例子。一辆汽车它有自己的参数,像是功率,总行驶路程等,它也可以做出不同的动作,像是启动,前进,后退等。这就是我们描述它的方式。将这一·方式对应到 C++ 语言里面是什么?联系之前结构体的知识,参数就是它的成员,动作就是它的成员函数。现在我们将这些补充到载具类里面。

class Vehicle{
public:
void Run();
void Move();
void Back();

int Power;
int Distance;
};

不过,我们现在的函数仅仅只是声明了,我们也可以在类外定义它们。

void Vehicle::Run(){
cout<<"Run!"<<endl;
}

void Vehicle::Move(){
cout<<"Move!"<<endl;
}

void Vehicle::Back(){
cout<<"Back!"<<endl;
}

然后,再像这样去使用它们。

Vehicle car;
car.Run();
car.Move();
car.Back();

结果

Run!
Move!
Back!

这样,我们就实现了一个载具类。

基础机制

公有、保护与私有成员

相信你们已经发现了,我们刚刚定义的 Vehicle 类的作用域最前面有一段 public: ,这是什么意思呢?这段代码的意思是:以下内容属于本类的公有成员。而公有成员是一个类最开放的一类成员,你可以将其视作结构体的成员,在类外都可随意访问。

除此之外,我们还有保护与私有成员。其中,保护成员只能在本类与子类里面被访问,私有成员则是只有本类中可以访问。这两种类型的存在保证了类的封装性,也是类核心功能和主要特征的基础。

来,让我们回到 Vehicle 这个类。我们在之前给出了它的公有成员。接下来,让我们想一想,它会有哪些保护与私有成员呢?首先,一个载具大概率有它自己的所有者,而这个持有人的身份应当是保密的,至少是不能随意公开的,于是我们可以将它设置成私有成员。其次,这个载具也应当有自己的 ID ,不过,所有它衍生出来的载具子类也同样是可以拥有的,所以,我们将 ID 设置成保护成员。同时,为了能够在外部访问这些访问受限的变量,我们还应当在公有成员加入它们的外部接口。这样,我们便有了一个全新的,更加全面的 Vehicle 类。

class Vehicle{
public:
void Run();
void Move();
void Back();

string get_ID(){
return ID;
}
string get_name(){
return name;
}

int Power;
int Distance;
protected:
string ID;
private:
string name;
};

构造函数和析构函数

在我们拥有这么多成员之后,我们创建一个对象之后如果一一进行赋值未免也麻烦了一点,于是我们可以写一个构造函数。

在公有成员中声明:

Vehicle(int , int , string , string);

在类外定义:

Vehicle::Vehicle(int Power, int Distance, string ID, string name){
this->Power = Power;
this->Distance = Distance;
this->ID = ID;
this->name = name;
}

使用

Vehicle car(1,1,"0","0");

这样,我们在创建一个载具对象时就能轻松地去初始化它的成员了。

当然,有了构造函数就肯定会有析构函数。为了让整段程序的运行逻辑更加完整,我现在来为Vehicle 类写一个析构函数吧。

~Vehicle(){
Power = 0;
Distance = 0;
ID = "";
name = "";
}

这样,在程序结束的时候,系统就会自动调用析构函数消除 car 这个对象了。

继承

上文我们提到保护成员能在子类中被访问,现在我来介绍子类继承的机制。

继承有三种类型:公有继承,保护继承,私有继承。在公有继承中,子类会继承父类的公有成员为公有成员,保护成员为保护成员;在保护继承中,子类会继承父类的公有成员和保护成员为保护成员;在私有继承中,子类会继承父类的公有成员和保护成员为私有成员。

在代码中,子类的继承需要先构造父类再构造自身,而在析构时,会先析构自身再析构父类,可以理解成一个类似栈的结构。

这里我们以 Vehicle 的子类 Train 为例。

class Train:public Vehicle{
public:
Train(int Power, int Distance, string ID, string name, int speed):
Vehicle(Power, Distance, ID, name){
this -> speed = speed;
}
private:
int speed;
};

Train 类公有继承了 Vehicle 类,并新增了私有成员 speed 。

由于子类析构函数会自动调用父类的析构函数,所以我们在写 Train 类的析构函数时无需再手动调用 Vehicle 的析构函数了。

~Train(){
speed = 0;
}

虚基类

虚基类的出现是为了解决多继承中菱形继承的问题。简单来说,就是,我们现在有一个类 Vehicle,有两个公有继承的子类:Car 和 Bus,又有一个类 Minibus 同时公有继承了这二者。那么就会引发两个问题:1.多次继承 Vehicle 导致内存被浪费。2.当我们访问 Vehicle 的公有成员或保护成员时,会引发二义性问题,发生错误。所以,为了解决这个问题,我们必须使用虚基类。

#include<iostream>

using namespace std;

class Vehicle{
public:
int speed;
Vehicle(int speed){
this -> speed = speed;
}
};

class Car:virtual public Vehicle{
public:
Car(int speed):Vehicle(speed){}
};

class Bus:virtual public Vehicle{
public:
Bus(int speed):Vehicle(speed){}
};

class Minibus:public Car, public Bus{
public:
Minibus(int speed):Vehicle(speed),Car(speed),Bus(speed){}
};

int main()
{
Minibus a(100);
cout<<a.speed;
return 0;
}

结果

100

值得注意的是,虚基类的初始化由最底层的派生类负责(即Minibus),且只初始化一次

以上便是这篇文章的全部内容了。

赞(0)
未经允许不得转载:171主机测评 » C++入门基础(5):类与对象
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址