在面向对象编程的世界里,C++以其强大的特性而闻名。今天,我们将深入探讨C++的三大核心特性:封装、继承和多态。理解这些概念不仅有助于写出更好的代码,更是掌握C++面向对象编程精髓的关键。此外这三大特性都提供了程序员的一个良好的编程方式和编程习惯。大大简化了代码。让我们更加方便地调用、添加、引用已有的代码。
下面请跟着小编一起探究C++的三大特性。
封装是将数据(成员变量)和操作数据的方法(成员函数)捆绑在一起的机制,同时对外部隐藏对象的内部实现细节。只开放几个供用户调用的接口,剩下的接口程序员自己维护。也就是说用户只知道使用,但对内部的构成一无所知。内部构成只有程序员知道。此外,封装可以将几种不同的类集成到一起共同使用、维护。
class BankAccount {
private:
// 私有数据,外部无法直接访问
// 为了保护内部变量,防止被随意改动。从而导致程序出错。
std::string accountNumber;
double balance;
std::string password;
public:
// 公共接口,提供受控的访问方式
BankAccount(const std::string& accNum, const std::string& pwd)
: accountNumber(accNum), balance(0.0), password(pwd) {}
// 存款方法
bool deposit(double amount) {
if (amount > 0) {
balance += amount;
return true;
}
return false;
}
// 取款方法(带安全检查)
bool withdraw(double amount, const std::string& inputPwd) {
if (inputPwd == password && amount > 0 && amount <= balance) {
balance -= amount;
return true;
}
return false;
}
// 查询余额
double getBalance(const std::string& inputPwd) const {
if (inputPwd == password) {
return balance;
}
return -1; // 返回错误值
}
// 不能直接修改账户号码
std::string getAccountNumber() const {
return accountNumber;
}
};封装的核心思想:
1.数据隐藏:将重要的数据设为私有,只通过公共接口访问
2.接口与实现分离:用户只需知道如何使用,无需关心内部实现
3.安全性:防止外部代码意外修改对象状态

继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,保证我们开发时在原有基础不变的情况下进行扩展,新增函数和变量产生新的类。新产生的类统称为派生类。
就比如说我们在社会上的身份多种多样。可能我们在不同的场合、不同人际关系、不同的指标计划中扮演着不同的身份。在家庭中我们可能是孩子,在工作中我们可能是打工人,在项目中我们可能是指标计划的执行者。
因此我们具有多种不同的身份,如果要用C++中的类和对象一次性表示出来的话,那恐怕会有遗漏,如果新添加的代码和已完成而且经过测试的代码放在一起的话,那出了问题我们定位问题的效率是不高的。
所以我们需要用到类这个概念。让他帮我们重复添加代码。将已完成的代码和新添加的代码架起一座桥梁。
下面演示代码就是我们从不同身份的记录。
#include <iostream>
#include <string>
class Person
{
public:
Person(const std::string& name,const std::string& address,const std::string& tel,int age)
:_name(name)
,_address(address)
,_tel(tel)
,_age(age)
{}
std::string Name()
{
return _name;
}
std::string Address()
{
return _address;
}
std::string Tel()
{
return _tel;
}
int Age()
{
return _age;
}
protected:
std::string _name; // 姓名
std::string _address; // 地址
std::string _tel; // 电话
int _age = 18; // 年龄
};
class Child : public Person
{
public:
Child(const std::string& father,
const std::string& mother,
const std::string& name,
const std::string& address,
const std::string& tel,
int age)
:_father(father)
,_mother(mother)
,Person(name,address,tel,age)
{}
std::string Father()
{
return _father;
}
std::string Mother()
{
return _mother;
}
std::string Information()
{
return Person::_name + std::to_string(Person::_age);
}
protected:
std::string _father;
std::string _mother;
};
int main()
{
Child child("bill","salary","snow","湖南省","193-5996-3852",20);
std::cout << child.Address() << ":" << child.Information() << std::endl;
return 0;
}继承方式可以分为public、protested、private,我一般想把他们称为3P方式,和类中的三大访问限定符——公有(public)、保护(protected)、私有(private)是一样的。
继承方式实际上决定着派生类继承基类的访问限定符所代表的那部分的大小。举个例子,派生类继承方式public继承基类。下面的代码。
当我们使用public继承时可以继承到基类的公有部分和保护部分。并且这些都在对应的区域中。基类的public访问限定中包含的函数和变量在派生类public访问限定中。同理protected访问限定中包含的函数和变量在派生类protected访问限定中。但是private子类就不能继承了,private相当于就是父类私有的部分。譬如说养老金、保健用品之类的。
protected继承其实和public是一样的。就是加上了一点限制。派生类public区域只能访问到protected区域。protected区域也只能访问到protected区域。
private继承相当于被家长扫地出门。什么不可见。
#include <iostream>
#include <string>
class Parent
{
public:
Parent(const std::string& name,int age)
:_name(name)
,_age(age)
{}
std::string Name()
{
return _name;
}
protected:
int Age()
{
return _age;
}
private:
std::string _name;
int _age;
std::string _household; // 户口,孩子以后会继承父母的户口。
int _money; // 孩子以后会继承父母的遗产。
};
class Child : public Parent
{
public:
Child(const std::string& name,int age)
:Parent(name,age)
{}
// 继承
std::string Child_Own_Father()
{
return Name();
}
protected:
int Father_Age()
{
return Age();
}
private:
//void change_test()
//{
// Parent::_name = "laozi";
//}
// 暂时不写。
};
int main()
{
Child c("小十三",13);
std::cout << c.Child_Own_Father() << std::endl;
std::cout <<c.Name() << std::endl;
return 0;
}如果函数、变量不构成重名,那就不构成关系。只要是重名,不管是返回类型、参数类型、参数个数不同都构成隐藏。
基类的友元关系,派生类是不能继承的。相当于朋友是一种私人资源,可以让朋友访问自己,但是不允许朋友访问孩子。也就是说基类友元不能访问派⽣类私有和保护成员。就相当于父债子不偿。
#include <iostream>
#include <string>
using namespace std;
class Student;
class Person
{
public:
friend void Display(const Person& p, const Student& s);
friend void Print();
protected:
string _name; // 姓名
};
class Student : public Person
{
protected:
int _stuNum; // 学号
};
void Display(const Person& p, const Student& s)
{
cout << p._name << endl;
//cout << s._stuNum << endl;
}
int main()
{
Person p;
Student s;
// 编译报错:error C2248: “Student::_stuNum”: ⽆法访问 protected 成员
// 解决⽅案:Display也变成Student 的友元即可
Display(p, s);
return 0;
}无论有多少种继承关系、继承基类的派生类,基类的静态变量永远只有一个。
#include <iostream>
#include <string>
using namespace std;
class Student;
class Person
{
public:
int NUM()
{
std::cout << "Num:" << (void*)&_num << std::endl;
return _num;
}
protected:
static int _num;
};
// 静态变量要在类域外创建,因为不管类对象有多少个。静态变量只能有一个。
int Person::_num = 0;
class Student : public Person
{
public:
int NUM()
{
std::cout << "Num:" << (void*)&_num << std::endl;
return _num;
}
protected:
};
int main()
{
Person p;
Student s;
p.NUM();
s.NUM();
std::cout << "地址都是相同的,这两个就是同一个变量。" << std::endl;
return 0;
}下期小编想讲红黑树,欢迎各位大佬捧场!
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=7ud7omulz49