封装
面向对象三大特性:封装、继承、多态
封装
属性、行为、实例化
一个类里封装了它的属性(成员变量)、行为(成员函数),通过public、private、protected来控制访问权限。
在需要对象时,通过实例化(通过类来生成对象的过程)来生成对象。
/*
封装的语法
class 类名{
访问权限:
属性(成员变量)
行为(成员函数)
}
*/
class People{
// 访问权限 public、private、protected
public:
//属性
int m_Id; //m -> member
int m_Age;
//行为
void fun(int id){
m_Id = id;
}
}
int main(){
//通过类来生成对象的过程,叫 实例化
People p;
//访问对象的属性
p.m_Id = 1;
p.fun(2);
return =;
}
访问权限
公共权限 public 类内可以访问,类外也可以访
保护权限 protected 类内可以访问,类外不可以访问 子类可以访问
私有权限 private 类内可以访问,类外不可以访问 子类不可以访问
#include<iostream>
using namespace std;
class People {
//公有权限
public:
int m_Id;
//保护权限
protected:
int m_HouseId;
//私有权限
private:
int m_PayPass;
public://
void work() {
//所有成员变量,类内均可访问
m_Id = 1;
m_HouseId = 12138;
m_PayPass = 000000;
}
private:
void fun() {
m_Id = 1;
m_HouseId = 12138;
m_PayPass = 000000;
}
};
class Son : public People {
void fun() {
m_Id = 2;
m_HouseId = 3; //保护成员,子类可以访问
m_PayPass = 111; //私有成员,子类无法访问
}
};
int main() {
//实例化
People p;
p.m_Id = 1; //公共成员,类外可以访问
p.m_HouseId = 5; //保护成员,类外不可访问
p.m_PayPass = 1111; //私有成员,类外不可访问
p.work();
p.fun(); //私有成员函数,类外不可访问
return 0;
}
class和struct的区别
C++中,class和struct只有访问权限的区别
struct 默认是公共的 (C++中可以定义成员函数,C中不可以)
class 默认是私有的
#include<iostream>
using namespace std;
class C {
int m_a;
};
struct S {
int m_a;
void fun() {
m_a = 666;
}
};
int main() {
C c;
S s;
c.m_a = 4; //私有的,访问不到
s.m_a = 5; //公有的,能访问
s.fun(); //struct可以定义成员函数
return 0;
}
属性私有化
把成员属性私有化,提供公有方法来对数据进行访问
- 可以控制读写权限(提供
Get、Set方法) - 可以检测数据的有效性(在
Set方法中判断数据有效性)
#include<iostream>
using namespace std;
//接口、方法、函数 是一个概念
class Hero {
public:
void SetName(string name) {
m_Name = name;
}
string GetName() {
return m_Name;
}
int GetSkillCount() {
return m_SkillCount;
}
void SetSpeed(int speed) {
if(speed < 100 || speed > 500){
cout << "速度不合法" << endl;
return;
}
m_Speed = speed;
}
private:
string m_Name; //可读、可写
int m_SkillCount = 4; //只读
int m_Speed; //只写
};
int main() {
Hero h;
h.SetName("无极剑圣");
cout << h.GetName() << endl;
cout << h.GetSkillCount() << endl;
h.SetSpeed(666);
}
对象特性
构造函数
构造函数由程序员实现、由编译器调用。(若程序员没有主动实现构造函数,编译器提供一个默认构造函数,里面没有任何实现)
class People{
public:
//构造函数
People(){
初始化成员变量
}
int 成员变量;
string 成员变量;
}
注意:
- 函数名称与类名保持一致
- 返回值类型 不需要写
- 构造函数可以有参数
#include<iostream>
#include<string>
using namespace std;
//构造函数需要注意的点
/*
* 1、函数名称与类名保持一致
* 2、返回值类型 不需要写
* 3、构造函数可以有参数
*/
class Hero {
public:
//构造函数
//默认(无参)构造函数
Hero() {
m_Name = "";
m_SkillCount = 4;
m_Speed = 200;
cout << " 默认构造函数:hero 构造完毕" << endl;
}
//有参构造函数(可以有多个)
//有参构造函数1
Hero(string name) {
m_Name = name;
m_SkillCount = 4;
m_Speed = 200;
cout << " 有参构造函数1:hero 构造完毕"<< m_Name << endl;
}
//有参构造函数2
Hero(string name, int skillCount) {
m_Name = name;
m_SkillCount = skillCount;
m_Speed = 200;
cout << " 有参构造函数2:hero 构造完毕"<< m_Name << endl;
}
private:
string m_Name;
int m_SkillCount = 4;
int m_Speed;
};
int main() {
Hero h1;
Hero h2("无极剑圣");
Hero h3(); // 这其实是函数声明 int main(); 、 int work(); 类型 函数名();
Hero h4{}; //默认(无参)
Hero h5 = Hero("齐天大圣");
}
析构函数
析构函数给对象进行反初始化(数据清洗),在对象销毁前,由系统自动调用。(若程序员没有主动实现,编译器提供一个默认析构函数,里面没有任何实现)
class People{
public:
//构造函数
People(){
初始化成员变量
}
//析构函数
~People(){
反初始化成员变量
}
int 成员变量;
string 成员变量;
}
注意:
- 函数名称和类名一致,并且在最前面加上一个
~波浪号 - 函数返回值不需要写
- 不能有参数
class Hero {
public:
//构造函数
Hero() {
cout << " 默认构造函数调用完毕" << endl;
}
//析构函数
~Hero() {
cout << " 析构函数调用完毕" << endl;
}
private:
string m_Name;
int m_SkillCount = 4;
int m_Speed;
};
int main() {
Hero h;
}
拷贝构造函数
调用别的对象的数据来生成新的对象(使用常量引用防止调用的对象内容被修改)
拷贝构造函数定义:类名(const 类型& 变量名){}
class People{
public:
//构造函数
People(){
初始化成员变量
}
//拷贝构造函数
// 调用别的对象的数据来生成新的对象
//(const People& h) 常量引用
// 使用引用传入别名,避免拷贝开销
// 使用常量防止h的成员变量被修改
People(const People& h){
成员变量 = h.成员变量;
}
//析构函数
~People(){
反初始化成员变量
}
int 成员变量;
string 成员变量;
}
-
用已经创建的对象来初始化对象
void func1() { cout << "-------------func1-------------" << endl; Hero h1("20"); Hero h2(h1); }

-
函数的传参
void test1(Hero h) { } void test2(Hero* h) { } void func2() { cout << "-------------func2-------------" << endl; Hero h1; test1(h1); //test2(&h1);//传入指针,没有生成新的对象,不会调用构造函数 }![]()
-
函数的返回值
Hero test3() { Hero h("40"); return h; } void func3() { cout << "-------------func3-------------" << endl; Hero h = test3(); }
#include<iostream>
#include<string>
using namespace std;
class Hero {
public:
//默认构造函数
Hero() {
m_Name = "大圣";
cout << " 默认构造函数调用完毕" << endl;
}
//有参构造函数
Hero(string name) {
m_Name = name;
cout << " 有参构造函数调用完毕" << endl;
}
//拷贝构造函数
Hero(const Hero& h) {
m_Name = h.m_Name;
cout << " 拷贝构造函数调用完毕" << endl;
}
//析构函数
~Hero() {
cout << " 析构函数调用完毕" << endl;
}
private:
string m_Name;
};
void func1() {
cout << "-------------func1-------------" << endl;
Hero h1("20");
Hero h2(h1);
}
void test1(Hero h) {
}
void test2(Hero* h) {
}
void func2() {
cout << "-------------func2-------------" << endl;
Hero h1;
test1(h1);
test2(&h1);//传入指针,没有生成新的对象,不会调用构造函数
}
Hero test3() {
Hero h("40");
return h;
}
void func3() {
cout << "-------------func3-------------" << endl;
Hero h = test3();
}
int main() {
func1();
func2();
func3();
return 0;
}
初始化列表
初始化列表的语法:构造函数(传参1,传参2): 成员变量1(传参1),成员变量2(传参2){}
#include<iostream>
#include<string>
using namespace std;
/*
初始化列表的语法
构造函数(传参1,传参2): 成员变量1(传参1),成员变量2(传参2){}
*/
class Hero {
public:
//有参构造函数
//Hero(string name,int hp) {
// m_Name = name;
// m_Hp = hp;
//}
Hero(string name, int hp) :m_Name(name), m_Hp(hp) {
}
void Print() {
cout << "英雄:" << m_Name << "的血量是:" << m_Hp << endl;
}
private:
string m_Name;
int m_Hp;
};
int main() {
Hero h1("无极剑圣", 100);
h1.Print();
return 0;
}
静态成员变量
特点:
- 所有对象共享同一份数据
- 编译阶段分配内存
- 需要在类内进行声明,在类外进行初始化
#include<iostream>
#include<string>
using namespace std;
class Hero {
public:
Hero() {
m_Name = "剑圣";
m_Hp = 100;
}
~Hero() {
}
//1.声明
static int m_HeroCount;//静态成员变量
private:
string m_Name;
int m_Hp;
};
//2.初始化
int Hero::m_HeroCount = 100;//不初始化就会link错误
int main() {
Hero h1;
cout << h1.m_HeroCount << endl;
cout << Hero::m_HeroCount << endl;
cout << &(h1.m_HeroCount) << endl;
cout << &(Hero::m_HeroCount) << endl;
return 0;
}
静态成员函数
特点:
- 所有对象共享函数
- 静态成员函数内部只能用静态成员变量
#include<iostream>
#include<string>
using namespace std;
class Hero {
public:
Hero() {
m_Name = "剑圣";
m_Hp = 100;
}
~Hero() {
}
static int m_HeroCount;
static int GetHeroCount() {
return m_HeroCount;
}
private:
string m_Name;
int m_Hp;
};
int Hero::m_HeroCount = 100;
int main() {
Hero h1;
cout << h1.GetHeroCount << endl;
cout << Hero::GetHeroCount << endl;
return 0;
}
this指针
作用:
- 解决命名冲突
- *this 就可以获取到这个对象本身
this代表这个对象的地址
| this | *this |
|---|---|
| &h | *(&h)==h |
class Hero {
public:
Hero(int hp) {
this->hp = hp;
//*(this).hp = hp; 作用同上
cout << this << endl;
}
int hp;
};
int main() {
Hero h(100);
cout << h.hp << endl;
cout << &h << endl;
return 0;
}

const修饰成员函数
常函数:常量对象只能调用常函数
#include<iostream>
#include<string>
using namespace std;
//常函数
class Hero {
public:
Hero(int hp) {
this->hp = hp;
cout << this << endl;
}
int GetHp() const {//常函数不能修改成员变量的值
//hp += hp;//错误,hp不能修改
return hp;
}
int SetHp(int hp){
this->hp = hp;
}
private:
int hp;
};
int main() {
const Hero h;//常量h 常量对象只能调用常函数
//h.SetHp(100);//无法修改h里的值
h.Gethp();//可以获得h里的值
}
mutable关键字
mutable <-> const
为了让常函数使用修改成员变量,给成员变量加上mutable关键字
#include<iostream>
#include<string>
using namespace std;
class Hero {
private:
int m_Hp;
mutable int m_getHpCounter;//加上mutable关键字
public:
Hero() :m_Hp(2), m_getHpCounter(0){
}
int getHp() const {//常函数中就能使用m_getHpCounter了
m_getHpCounter++;
return m_Hp;
}
void printCounter() const {//常函数中就能使用m_getHpCounter了
cout << m_getHpCounter << endl;
}
};
int main() {
Hero h;
h.getHp(), h.getHp(), h.getHp(), h.getHp(), h.getHp(), h.getHp(), h.getHp(), h.getHp();
h.printCounter();
return 0;
}
友元
目的:让一个类或函数能够访问另一个类的私有成员
友元的关键字:friend
三种友元:
1. 全局函数作为友元
函数作为友元,访问了People的私有变量
#include<iostream>
#include<string>
using namespace std;
class People {
friend void friendVisit(People* p);//函数作为友元,访问了People的私有变量
public:
People() {
m_House = "大别野";
m_Car = "玛莎拉蒂";
}
public:
string m_House;
private:
string m_Car;
};
void friendVisit(People* p) {
cout << "你的朋友访问了你的" << p->m_House << endl;
cout << "你的朋友访问了你的" << p->m_Car << endl; //没有在class里加上friend void friendVisit(People* p) 前,此处报错,不能访问私有成员变量
}
int main() {
People p;
friendVisit(&p);
return 0;
}
2. 类作为友元
类作为友元,访问了People的私有成员变量
#include<iostream>
#include<string>
using namespace std;
class People {
friend class PeopleFriend;//PeopleFriend类作为友元,访问了People的私有成员变量
public:
People() {
m_House = "大别野";
m_Car = "玛莎拉蒂";
}
public:
string m_House;
private:
string m_Car;
};
class PeopleFriend {
public:
PeopleFriend() {
}
void visit(People* p) {
cout << "你的朋友访问了你的" << p->m_House << endl;
cout << "你的朋友访问了你的" << p->m_Car << endl;//没有在class里加上friend class PeopleFriend前,此处报错,不能访问私有成员变量
}
};
int main() {
People p;
PeopleFriend pf;
pf.visit(&p);
return 0;
}
3. 成员函数作为友元
类的成员函数作为友元,访问了People的私有成员变量
注意:想要作为友元的类(PeopleFriend)的定义要放在要访问私有成员的类(People)的前面,否则People定义友元时不知道PeopleFriend里有成员函数
#include<iostream>
#include<string>
using namespace std;
class People;
class PeopleFriend {
public:
PeopleFriend() {
}
void visitAll(People* p);
void visitPub(People* p);
};
class People {
friend void PeopleFriend::visitAll(People* p);//只把想要作为友元的函数放在这
public:
People() {
m_House = "大别野";
m_Car = "玛莎拉蒂";
}
public:
string m_House;
private:
string m_Car;
};
void PeopleFriend::visitAll(People* p) {
cout << "你的朋友访问了你的" << p->m_House << endl;
cout << "你的朋友访问了你的" << p->m_Car << endl;
}
void PeopleFriend::visitPub(People* p) {
cout << "你的朋友访问了你的" << p->m_House << endl;
//cout << "你的朋友访问了你的" << p->m_Car << endl;//此处报错,不是友元,无法访问私有成员
}
int main() {
People p;
PeopleFriend pf;
pf.visitAll(&p);
pf.visitPub(&p);
return 0;
}

浙公网安备 33010602011771号