类的基础
类与对象的定义
核心概念
- 类(class):C++面向对象(OOP,Object Oriented Programming)的核心概念,是对现实世界事物的抽象描述——包含事物的属性(数据) 和行为(方法)。
- 语法层面:增加了函数的结构体;
- 逻辑层面:增加了数据行为的结构体(结构体仅侧重存储属性)。
- 对象(Object):类类型定义的变量,是类的实例化产物,对应现实世界中的具体事物。
- 例:
Cat tom;中,tom是Cat类的对象。
- 例:
现实世界抽象示例
| 现实事物 | 属性(数据) | 行为(方法) |
|---|---|---|
| 小猫 | 毛色、体重、性别、年龄 | 进食、睡觉、卖萌 |
| 文件 | 类型、权限、大小 | 打开、关闭、读写 |
| 进度条 | 尺寸、百分比、颜色 | 进度更新、弹窗提示 |
| 电视机 | 尺寸、品牌、音量、频道、稳压器、电路板 | 开机、关机、切换频道、调节音量 |
语法格式
class 类名 {
public: // 成员限定符(后续详细讲解)
// 成员属性(数据)
数据类型 属性名1;
数据类型 属性名2;
...
// 成员方法(行为/函数)
返回值类型 方法名1(参数列表) {
方法实现;
}
返回值类型 方法名2(参数列表) {
方法实现;
}
...
};
基础示例代码
#include <iostream>
using namespace std;
// 自定义类类型 A
class A {
public:
// 成员属性
int x;
float y;
// 成员方法
void showInfo() {
cout << "x:" << x << endl;
cout << "y:" << y << endl;
}
};
// 主函数中使用类
int main(void) {
A a; // 定义A类的对象a(类变量 = 对象)
// 访问公有属性并赋值
a.x = 100;
a.y = 1.2f;
// 调用公有方法
a.showInfo();
return 0;
}
类与结构体(C语言)的区别
| 对比项 | 结构体(C语言) | 类(C++) |
|---|---|---|
| 成员类型 | 仅支持数据属性 | 支持数据属性 + 成员方法 |
| 默认访问权限 | 公有(public) | 私有(private) |
| 核心用途 | 存储数据集合 | 抽象事物(属性+行为封装) |
唯二关键区别:
- 类支持成员方法(函数),结构体仅支持数据;
- 类默认访问权限为private,结构体默认public。
类方法
核心概念
类方法是类中的函数接口,用于描述对象的行为属性,必须通过对象(或类,静态方法除外)调用。
定义与调用示例
#include <iostream>
using namespace std;
class Kitty {
public:
// 成员方法(行为)
void eat() { cout << "小猫进食" << endl; }
void sleep() { cout << "小猫睡觉" << endl; }
void actCute() { cout << "小猫卖萌" << endl; }
};
int main(void) {
Kitty myCat;
// 正确:通过对象调用非静态方法
myCat.eat(); // 输出:小猫进食
myCat.sleep(); // 输出:小猫睡觉
myCat.actCute();// 输出:小猫卖萌
// 错误:非静态方法不能直接通过类调用(需对象实例)
// Kitty::eat();
return 0;
}
类方法设计原则
- 仅将与对象核心行为相关的逻辑封装为类方法(如小猫的“进食”,而非“被人类抱起”);
- 需考虑继承场景:通用行为(如动物的“呼吸”)在父类实现,特殊行为(如鸟的“飞行”)在子类实现;
- 方法需提供清晰接口,内部逻辑对外部透明(封装特性)。
类成员权限限定符
三种权限定义与访问范围
类通过权限限定符控制成员的访问范围,核心目的是封装保护(隐藏内部实现,暴露安全接口)。
| 限定符 | 访问范围 | 核心特点 |
|---|---|---|
| public(公有) | 类内、类外、子类均可访问 | 对外暴露的接口(方法/属性) |
| protected(保护) | 类内、子类可访问,类外不可访问 | 继承场景下的中间权限 |
| private(私有) | 仅类内可访问,类外、子类均不可访问 | 需保护的核心属性/内部方法 |
注意:类中未显式标注限定符的成员,默认是private(结构体默认public)。
语法示例代码
#include <iostream>
using namespace std;
class A {
int w; // 默认:私有成员(private)
private:
int x; // 私有成员
protected:
int y; // 保护成员
public:
int z; // 公有成员
// 类内方法可访问所有权限的成员
void f() {
w = 10; // 合法:类内访问私有成员
x = 100; // 合法:类内访问私有成员
y = 200; // 合法:类内访问保护成员
z = 300; // 合法:类内访问公有成员
}
};
int main(void) {
A a;
// 错误:类外无法访问私有/保护成员
// a.w = 20;
// a.x = 200;
// a.y = 300;
// 正确:类外可访问公有成员
a.z = 400;
a.f(); // 正确:调用公有方法(方法内部访问私有/保护成员)
return 0;
}
权限设计基本原则
- 成员属性:优先设为
private(禁止外部直接修改,避免逻辑错误);- 若需修改/获取属性,通过公有方法封装(如
setAge(int age)进行边界检测);
- 若需修改/获取属性,通过公有方法封装(如
- 成员方法:优先设为
public(对外提供行为接口);- 内部辅助逻辑设为
private(如计算辅助函数); - 继承场景下需子类复用的方法设为
protected。
- 内部辅助逻辑设为
构造函数(特殊成员方法)
核心概念
- 用途:对象创建时自动调用,用于初始化成员属性(避免属性为随机值);
- 特点:无返回值(不可写
void),函数名与类名完全一致; - 分类:无参构造、带参构造、默认参数构造。
语法示例代码
#include <iostream>
#include <string>
using namespace std;
class Cat {
private:
// 私有成员属性(遵循权限设计原则)
string Name;
string Color;
char Sex;
int Age;
public:
// 1. 无参构造函数(默认构造)
Cat() {
cout << "无参数的构造版本.." << endl;
Name = "Tom";
Color = "Red";
Sex = 'M';
Age = 1;
}
// 2. 带参构造函数(含默认参数)
Cat(const string name, const string color, const int age = 1, const char sex = 'N') {
cout << "带参数的构造版本.." << endl;
Name = name;
this->Color = color; // this指针:指向当前对象,区分成员变量与参数名
this->Sex = sex;
this->Age = age;
}
// 公有方法:访问私有属性
void showInfo() {
cout << "Name: " << Name << endl;
cout << "Color: " << Color << endl;
cout << "Sex: " << Sex << endl;
cout << "Age: " << Age << endl;
cout << "--------------------" << endl;
}
// 公有方法:修改私有属性(带边界检测)
void setAge(int age) {
if (age >= 100) age = 99; // 防止不合理值
Age = age;
}
};
// 主函数测试
int main(int argc, char const *argv[]) {
Cat tom; // 调用无参构造
tom.showInfo();
Cat jarry("Jarry", "黄色"); // 调用带参构造(默认age=1,sex='N')
jarry.setAge(199); // 调用公有方法修改私有属性(最终age=99)
jarry.showInfo();
Cat jarryBrother("JarryBrother", "灰色", 3, 'M'); // 显式传所有参数
jarryBrother.showInfo();
// 拷贝构造(预习内容):用已有对象初始化新对象
Cat j1 = jarry;
j1.showInfo();
return 0;
}
关键注意事项
- 若未自定义构造函数,编译器会生成默认无参构造(空实现);
- 若自定义了带参构造,编译器不再生成默认无参构造(需手动显式定义);
- 默认参数需放在参数列表末尾(如
const int age = 1, const char sex = 'N'); this指针:隐含在非静态成员方法中,指向当前对象,用于区分成员变量与参数名(如this->Color = color)。
拓展(补充核心知识点)
this指针详解
- 本质:非静态成员方法的隐含参数(编译器自动添加),类型为
类名* const(指针本身不可修改); - 用途:
- 区分成员变量与函数参数名(如
this->Age = age); - 在方法中返回当前对象(
return *this,支持链式调用);
- 区分成员变量与函数参数名(如
- 注意:静态方法中无
this指针(静态方法不依赖对象实例)。
链式调用示例
class Calculator {
private:
int result;
public:
Calculator() { result = 0; }
Calculator& add(int num) { // 返回对象引用
result += num;
return *this; // 返回当前对象
}
Calculator& sub(int num) {
result -= num;
return *this;
}
void showResult() { cout << "结果:" << result << endl; }
};
// 调用:链式调用多个方法
Calculator cal;
cal.add(10).sub(3).add(5); // 结果 = 0+10-3+5=12
cal.showResult();
成员变量命名规范(行业通用)
- 私有成员变量前加下划线(如
_name、_age),避免与参数名冲突(减少this指针使用);class Cat { private: string _name; // 私有成员加下划线 int _age; public: void setName(string name) { _name = name; } // 无需this指针 }; - 类名首字母大写(如
Cat、Monster),方法名首字母小写(如showInfo、setAge)。
静态成员(static)基础
- 静态成员变量:
- 所有对象共享同一数据(如“人类的共同属性:物种=人类”);
- 需在类外初始化(
数据类型 类名::变量名 = 初始值); - 可通过类名直接访问(
类名::变量名),无需对象实例。
- 静态成员方法:
- 无
this指针,只能访问静态成员变量/方法; - 可通过类名或对象调用。
- 无
示例代码
class Human {
public:
static string species; // 静态成员变量(所有人类共享)
static void showSpecies() { // 静态成员方法
cout << "物种:" << species << endl;
}
};
// 类外初始化静态成员变量
string Human::species = "智人";
int main() {
// 无需对象,直接通过类名访问
Human::showSpecies(); // 输出:物种:智人
Human::species = "人类";
Human p1, p2;
p1.showSpecies(); // 输出:物种:人类(共享数据)
return 0;
}
析构函数基础
- 用途:对象销毁时(生命周期结束)自动调用,用于释放资源(如动态内存、文件句柄);
- 特点:无返回值,无参数,函数名前加
~,与类名一致; - 示例:
class File { private: FILE* _file; public: // 构造函数:打开文件 File(const char* filename) { _file = fopen(filename, "r"); } // 析构函数:关闭文件(释放资源) ~File() { if (_file != NULL) fclose(_file); cout << "文件已关闭" << endl; } };

浙公网安备 33010602011771号