目录
数据抽象
类的定义
成员变量
成员函数
创建对象
this指针
数据抽象
在前面我们介绍了许多的基本数据类型,可以表示常用的数字与文字信息,也介绍了可以将形同数据串起来的数组,但是这些都是远远不够的,在这个数据化的时代,每一个人都会衍生出非常庞大的数据量,在学习c++语言中我们常用一个人的基本信息来讲解。
//面向对象1 //作者:分解机226 #include#include using namespace std; int main() { string Studentname = "张三"; int StudentID = 20201414; int StudentClass = 5; cout << "学生学号是" << StudentID << endl; cout << "学生班级是" << StudentClass << endl; cout << "学生姓名是" << Studentname << endl; return 0; }
上面的做法可以直接的了解一个学生的基本信息,但是如果在学生很多的情况下,这样的方法就会显得非常的繁琐。
//面向对象1 //作者:分解机226 #include#include using namespace std; int main() { string Studentname[2] = { "张三", "里斯" }; int StudentID[2] = { 20201414,20201415 }; int StudentClass[2] = { 5,6 }; for (int i = 0; i < 2; i++) { cout << "学生学号是" << StudentID [i] << endl; cout << "学生班级是" << StudentClass[i] << endl; cout << "学生姓名是" << Studentname [i] << endl; cout << endl; } return 0; }
我们有用数组的方法去实现了这一功能,但是数组也会有局限性,我们要注意每个数组的大小要一致,有读者会想到使用二维数组,但是二维数组不适合存储名字,这就需要一种存储复合类型的数组,这种数组就是结构体(Struct)。
//面向对象1 //作者:分解机226 #include#include #include using namespace std; struct student { int ID; int Classnum; string name; }; int main() { vector students; student stu1; stu1.ID = 5; stu1.Classnum = 12; stu1.name = "张三"; students.push_back(stu1); student stu2; stu2.ID = 520; stu2.Classnum = 1234; stu2.name = "张三的数据库"; students.push_back(stu2); for (int i = 0; i < 2; i++) { cout << "学生学号是" << students[i].ID << endl; cout << "学生班级是" << students[i].Classnum << endl; cout << "学生姓名是" << students[i].name<< endl; cout << endl; } }
在这里我们使用了struct关键字定义了一个结构体,在其中放入任何数据类型的变量就相当于一下子定义了好几个变量,我们使用点号(.)来获取结构体中的成员,这样定义几个学生,只需要一个包含Student结构体的数组就可以了。
提到面向对象就不得不了解封装、继承、多态,
封装,其实就是隐藏细节,将一个复杂的装置封装在一个看不见的黑盒中,只暴露出接口,函数就体现了封装的思想,我们在使用函数的时候只关心函数的参数、返回值以及函数的作用,并不需要关心函数内部的代码。
面向对象的目的是抽象的表现现实中的事务,在现实中也会有分类的问题,现实中有许多的事务之间有相同的特点,在设计类的时候为了避免数据的重复,我们就会使用继承来让类形成一个层次结构,
继承也是为了实现多态而存在的,所谓多态就是不同的类具有相似的行为比如飞机和汽车都有加速行为,但是实现的方式不同,在C++中我们可以使用虚函数声明同名的函数并具体的在不同的类中进行实现,而最后能用一种方式调用这个函数。
类的定义
面向对象的核心是类,从类创建出来的具体变量叫做对象(Object)对象可以看作是类的实例,类是一个抽象的概念,先来看一个简单的类。
//面向对象1 //作者:分解机226 #include#include #include using namespace std; class BOLI { public: BOLI(int id, string nm, int hp, int mn, int dmg) { ID = id; name = nm; mana = mn; HP = hp; damage = dmg; } void aaa(BOLI& boli) { boli.takeDamage(this->damage); } void takeDamage(int incomingDmg) { HP -= incomingDmg; } private: int ID; string name; int HP;//血量 int mana;//魔法值 int damage;//伤害值 };
上面的代码定义了一个简单的类,这个类定义了一般游戏中的英雄,在其中定义了名字,血量等必要的属性,并定义了两个函数,攻击aaa()和掉血takeDamage()。在攻击其他英雄时有参数传入的其他英雄会受到魔法伤害,进而调用伤害函数减少血量。
成员变量
类中可以定义各种成员变量,可以是基本的数据类型,也可以是其他类的对象,在一个类中也可以定义另一个类,不过这个类的作用域将仅限于这个类中;如果是公有访问级别,可以使用域操作符“::”在外部访问,
所谓的访问级别就是上面的public和private等关键字。private下面的成员变量一般仅限于类内部的成员函数访问,在main()函数以及其他地方是无法使用的,
成员函数
类中定义的函数叫做成员函数,成员函数在调用的时候需要像读取或修改成员变量一样加上对象名字作为前缀,成员函数可以在类内部定义也可以在外部定义,在外部定义的成员函数首先要在类中声明成员函数,然后再类外定义的同时在函数名前面加上类名和作用域操作符“::”。
//面向对象1 //作者:分解机226 #include#include #include using namespace std; class hero { public: hero(int id, string nm, int hp, int mn, int dmg); void aaa(hero&); void takedamage(int incomingdmg); private: int ID; string name; int HP; int mana; int damage; }; hero::hero(int id, string nm, int hp, int mn, int dmg) { ID = id; name = nm; HP = hp; mana = mn; damage = dmg; } void hero::aaa(hero& ch) { ch.takedamage(this->damage); } void hero::takedamage(int incomingdmg) { HP -= incomingdmg; }
上面的类展示了成员函数的定义和声明分离,我们在类的外部定义了3个函数,在函数名前面加上了类名“hero”和“::”以表示他们是成员函数,函数声明不需要指明函数的形参名字,所以在aaa()函数的声明中只写了“hero &”.无论是类外部还是内部的成员函数都是属于类的内部,可以访问所有的成员变量。
下面我们来讲讲构造函数,在前面有一个与类同名的特殊函数hero(),这样的函数叫做构造函数,构造函数的作用在于初始化类中的成员,它往往会在类实例化的时候被自动调用,
创建对象
//面向对象1
//作者:分解机226
#include
#include
#include
using namespace std;
class BOLI
{
public:
BOLI(int id,
string nm,
int hp,
int mn,
int dmg)
{
ID = id;
name = nm;
HP = hp;
mana = mn;
damage = dmg;
}
void aaa(BOLI& boli)
{
boli.takeDamage(this->damage);
}
void takeDamage(int incomingDmg)
{
HP -= incomingDmg;
}
int getHP()
{
return HP;
}
private:
int ID;
string name;
int HP;//血量
int mana;//魔法值
int damage;//伤害值
};
int main()
{
BOLI dj(20, "盖伦", 800, 100, 10);
BOLI bl(30, "剑圣", 400, 198, 4);
cout << "剑圣的初始血量:" << bl.getHP() << endl;
dj.aaa(bl);
cout << "剑圣受到盖伦的伤害值后的血量:" << bl.getHP() << endl;
return 0;
}
我们可以看到,在定义对象的的时候,类的名字被当作类型名使用。上面主函数中的dj和bl就是实例化的对象。
//面向对象1 //作者:分解机226 #include#include #include using namespace std; class BOLI { public: BOLI(int id, string nm, int hp, int mn, int dmg) { ID = id; name = nm; HP = hp; mana = mn; damage = dmg; } void aaa(BOLI& boli) { boli.takeDamage(this->damage); } void takeDamage(int incomingDmg) { HP -= incomingDmg; } int getHP() { return HP; } private: int ID; string name; int HP;//血量 int mana;//魔法值 int damage;//伤害值 }; int main() { BOLI dj(20, "盖伦", 800, 100, 10); BOLI bl(30, "剑圣", 400, 198, 4); cout << "剑圣的初始血量:" << bl.getHP() << endl; BOLI* chm = &dj; (*chm).aaa(bl ); chm->aaa(bl); cout << "剑圣受到盖伦的伤害值后的血量:" << bl.getHP() << endl; return 0; }
剑圣被攻击后的血量是380,因为在上述代码中剑圣被攻击了两次。
上面展示了指针访问对象成员的方法,我们可以看到我们可以先解引用,在使用普通的点符号,也可以直接使用指针专用的成员访问符“->”,两者是等价的。
this指针
成员函数访问成员时有一个隐含的指针变量this,它的类型是指向当前实例的指针,指向的是调用成员函数的对象。
//面向对象1 //作者:分解机226 #include#include #include using namespace std; class myclass { public: myclass(int a, int b) { this-> a= a; this->b = b; } int getA() { return this->a; } private : int a; int b; }; int main() { myclass bl(2, 3); cout << "a的值是:" << bl.getA() << endl; return 0; }
前面讲解了结构体和类这两个大类我们来看看它们的区别
在C语言时代结构体还没有构造函数和成员函数这些面向对象元素,现在C++结构体和类的区别就只剩下默认的访问控制符了,结构体默认访问控制符是public,类是private。
好本次面向对象就讲到这里,可以关注我我后面会更新(时间不会相隔太久)



