【系列专栏】:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来!
《QT开发实战》 《嵌入式通用开发实战》 《从0到1学习嵌入式Linux开发》 《Android开发实战》 《实用硬件方案设计》
长期持续带来更多案例与技术文章分享;
欢迎商业项目咨询,10年+软硬全栈内功,助力解决您的尊贵需求。
原文链接:https://cloud.tencent.com/developer/article/2235700
——————————————————————————————————
目录
C++面向对象有三大特征,分别是继承、多态和封装,接下来的三篇博文将会对这三大特性分别进行总结,并结合实例编程测试,加深理解,本次博文首先总结下C++的继承特征。
C++ 在 C 语言的基础上增加了面向对象编程, C++ 支持面向对象程序设计。类是 C++的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员,函数在一个类中被称为类的成员(C++中的类跟Java语言实在太像了)。
举个例子,一个人,他有名字、年龄等等这些属性,同时人也会吃饭、走路、睡觉,将人统称为一个类,类就抽象出来的一个概念,具体到是哪个人,就叫做对象。从类中实例化对象有两种方法:从栈中实例化、从堆中实例化。
下面自定义一个people类,看下如何自定义类和使用对象的。
在Ubuntu下新建一个03_class_people目录,其下新建一个03_class_people.cpp文件,代码如下:
#include <iostream>
#include <string>
using namespace std;
class People
{
public:
string name;
int age;
void speak(){
cout << "my name is " << name << ", age is " << age << endl;
}
};
int main()
{
//从栈中实例化对象
People people1;
people1.name = "小芳";
people1.age = 18;
people1.speak();
//从堆中实例化对象
People *people2 = new People();
if(NULL == people2){
return 0;
}
people2->name = "张三";
people2->age = 20;
people2->speak();
delete people2;
people2 = NULL;
return 0;
}
首先,定义了一个People类,内部定义了两个变量,一个方法,其中string 是C++的数据类型,使用频率很高;使用了public(公有的)访问限定符,目的为了下面使用类时调用这些变量和方法,若不加限定,默认的private(私有的);
然后,从栈中实例化一个对象people1,并为people1中的成员变量赋值,然后调用对象中的speak()方法打印输出;
接着,从堆中实例化一个对象people2(使用关键字 new 的都是从堆中实例化对象),这种方式需要开辟内存,指针会指向对应的内存空间,若申请内存失败,指针就会指向NULL,程序退出;赋值后,同样打印输出,最后释放内存。
编译程序,运行测试下:
从上面我们可以理清了C++中类和对象的概念,从类实例化出来的就是对象,对象拥有类的属性,可以从栈或堆中实例化出来。
构造函数在对象实例化时被系统自动调用,仅且调用一次。实际上定义类时, 如果没有人为定义构造函数和析构函数, 编译器就会生成一个构造函数和析构函数, 只是他们不会做任何事情,所以对我们来说不会关注到。构造函数特点:
析构函数与构造函数相反, 在对象结束其生命周期时系统自动执行析构函数。析构函数的特点:
下面举例说明这两个函数的使用。
在Ubuntu下新建一个04_structor目录,在其中新建一个04_structor.cpp文件,代码如下:
#include <iostream>
#include <string>
using namespace std;
class People
{
public:
People()
{
cout<<"构造函数执行!"<<endl;
};
~People()
{
cout<<"析构函数执行!"<<endl;
}
};
int main()
{
People people;
cout<<"构造与析构函数示例"<<endl;
return 0;
}
仍然是定义一个People类,然后自己写一个构造函数和析构函数,在函数中及main函数中打印信息。
我们运行程序,查看下打印的顺序:
可见执行顺序是:构造函数-》主函数-》析构函数,实例化对象时调用构造函数,然后main函数打印输出,最后对象生命周期结束时执行析构函数。
每个对象都拥有一个 this 指针, this 指针记录对象的内存地址,在 C++中, this 指针是指向类自身数据的指针, 简单的来说就是指向当前类的当前实例对象。类的 this 指针有以下特点:
下面举例说明this的用法。
在Ubuntu下新建一个05_this_pointer目录,在其中新建一个05_this_pointer.cpp文件,代码如下:
#include <iostream>
#include <string>
using namespace std;
class People
{
public:
string name;
void func();
};
int main()
{
People people;
people.func();
return 0;
}
void People::func()
{
this->name = "小芳";
cout << "她的名字叫:" << this->name << endl;
}
在类的成员函数中使用了this指针,指向类中的name成员,赋值后并将其打印了出来。
编译运行程序:
有了上面的类和对象基础,才好理解下面要讲的继承。继承允许我们依据一个类来定义另一个类,这使得创建和维护一个应用程序变得更容易,也可达到重用代码功能和提高执行效率的效果。
当创建一个类时,不用重新编写新的数据成员和成员函数,只需指定新建的类(派生类)继承了一个已有的类(基类)的成员即可,在 Qt 里大量的使用这种特性, 当 Qt 里的类不满足自己的要求时,我们可以重写这个类,就是通过继承需要重写的类,来实现自己的类的功能。
一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类。
类派生列表以一个或多个基类命名,形式如下:
class derived-class: access-specifier base-class
access-specifier:访问修饰符,与类的访问修饰限定符一样,可以使用public、 protected 或 private,若未使用,默认为private;
base-class:已经定义的某个类的名称;
下面对比下3种访问修饰符:
下面举个例子说明继承的使用。
接着1.1节的程序,有一个People类,其中已经定义了name、age、speak()方法,若不想重写这个People类,现在新建一个Animal类,让People类继承Animal类,若是共用继承,则People类实例对象中就可以使用Animal类中成员了。
在Ubuntu下新建一个06_inherit目录,在其中新建一个06_inherit.cpp文件,代码如下:
#include <iostream>
#include <string>
using namespace std;
//抽象出两个属性,各种动物都有的
class Animal
{
public:
string sex;
int weight;
};
//People类去继承Animal类
class People : public Animal
{
public:
string name;
int age;
void speak(){
cout << "my name is " << name << ", age is " << age << endl;
}
};
int main()
{
//从栈中实例化对象
People people;
people.name = "小芳";
people.age = 18;
people.sex = "女";
people.weight = 90;
cout << "我的名字叫 " << people.name << ",年龄 " << people.age << ",性别 " << people.sex << ",体重 " << people.weight << "斤" << endl;
return 0;
}
编译程序运行:
本次博文首先是总结了C++中类和对象的基本概念,给出了构造函数和析构函数的区别,并总结了this指针的使用方法,有了以上基础后,进一步总结了C++语言的三大特征之一继承的基本概念,并结合实例演示了继承的使用方法。
作于202303072230,已归档
———————————————————————————————————