C++的三大特性(面向对象的特点)

C++基础(3)

C++是面向对象的编程语言

C++是面向对象的语言,对于面向对象的语言,都是具有封装 继承和多态这几个特点的。

面向对象
C++中使用class来对某些具备相同特性的事物进行大致概述,比如人类,共同的属性有手,脚,脸部,头发等,在我们构建一个类的时候,这些属性就是这个类的属性,一些人类的行为就可以作为人类的方法。虽然有了这些属性和方法,但是类依旧是一个很抽象的存在。那么,在我们使用时,就需要把类实例化,也就是创建类对象。犹如女娲造人,造出来的人都是有自己的名字,样貌,性格等。

封装
对于类的属性,我们是很有必要设置它们的属性的,在C语言中,我们会用结构体struct来定义一个有多种类型组成的新类型,这应该就类的前身吧。一般的用法就是通过.->获取里面的属性,这是因为struct里面的属性默认是公开的(public)。
在C++的class中,属性默认是私有的(private)。类对象是不能直接访问类的私有成员属性的,打个比方,我们的名字一样,就应该设置为private,否则我们没事就去改一下,会出大问题的hh

#include <iostream>
#include <string>
using namespace std;

class Human{
public:
	Human(string name, int age, double height)
	: _name(name), _age(age), _height(height)
	{
	}
	void say_hello() {
		cout << "my name is " << _name << " and age:" << _age << endl;
	}
private:
	string _name;
	int _age;
	double _height;
};

int main() {
	Human h1("Busy", 21, 171.6); // 使用构造函数构造对象
	h1.say_hello();
	return 0;
}

输出结果:

my name is Busy and age:21

继承
C++的继承,通俗的来说就是子承父业,子类是拥有父类的全部属性和方法的,这样在开发过程中,就能避免多个类的某些方法属性是重复的,少些很多重复的代码,可以提高效率。C++中是支持多重继承的,即一个类可以继承多个类作为父类。

#include <iostream>
#include <string>

using namespace std;

// 定义父类
class Base {
public:
    Base(int num) 
    : _num(num) {
        
    }
    void print() {
        cout << "my number is " << _num << endl;
    }

private:
    int _num;
};

// 子类, 继承于Base父类
class Child : public Base {
public:
    Child(int num) : Base(num) // 子类继承了父类的属性,同时也继承了父类的方法,包括构造方法
    {

    }
};

int main() {
    // 创建Base类对象,创建时使用构造函数创建
    Base base(1);
    // 调用print方法
    base.print();

    // 创建一个子类对象,创建时使用构造函数创建
    Child child(20);
    child.print(); 

    return 0;
}

输出结果:

my number is 1
my number is 20

多态
多态的实现有两种方式,一种是动态实现(通过虚函数实现),另一种是静态实现多态(通过模板或函数重载实现),这里先描述类的多态实现。
动态多态是指在程序运行阶段,通过判断父类指针的指向来确定应该调用哪一个同名函数(子类会重写父类定义或声明的 virtual修饰的虚函数),从而满足程序的需要。

#include <iostream>

using namespace std;

class A {
public:
    virtual void func() {
        cout << "this is class A func()" << endl;
    }
};

class B : public A {
public:
    virtual void func() {
        cout << "this is class B func()" << endl;
    }
};

class C : public A {
    public:
    virtual void func() {
        cout << "this is class C func()" << endl;
    }
};

int main() {
    // 定义三个类对象,分别是A、B、C类的对象
    A a;
    B b;
    C c;

    // 一个父类指针
    // 父类指针指向分别指向三个类时调用func函数
    A *parent = &a;
    parent->func(); // 指向A

    parent = &b; // 指向B
    parent->func();

    parent = &c; // 指向C
    parent->func();

    return 0;
}

输出结果:

this is class A func()
this is class B func()
this is class C func()

那么动态多态是怎么使用虚函数来实现的呢?其实在父类把一个函数声明为虚函数时,这个类会维护一个虚函数表,在编译过程中只是把每一个虚函数方法这个虚函数表里面,在运行时通过父类指针的指向确定是需要调用哪一个类的虚函数,再到虚函数表里面找到该函数,然后调用。

// 证明是维护了一个虚函数表, 空类的字节大小为1,类的函数是不占类内存的
class E{
public:
    void print() {
        cout << "this is a empty class" << endl;
    }
};

class V{
public:
    virtual void print() {
        cout << "this class has a virtual function" << endl;
    }
};

int main() {
    
    cout << "empty class size : " << sizeof(E) << endl;

    cout << "has virtual function class size : " << sizeof(V) << endl;

    return 0;
}

输出结果:

empty class size : 1
has virtual function class size : 8 // 这里是8,因为我用的64位系统

总结

  • 封装使类的一些属性和方法更加安全,让使用者不必考虑实现,调用接口即可。
  • 继承能使某一部分具有相同属性或方法的类相关联,对于一些共性,可以统一化,对于特性也能自由发展。
  • 多态的使用可以让一个方法在不同指向时能展现不一样的效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值