C++: 类与对象基础

最后更新:2026-08-26

前面的课程里,我们用结构体把不同类型的变量组合成一个整体。

但真实世界的事物不仅有属性(如姓名、年龄),还有行为(如走路、说话)。

就是用来描述"事物"的——它把属性行为封装在一起。


1. 什么是类?

(1) 1.1 生活中的类

生活场景 程序中的对应
一份建筑设计图纸(描述了房子的结构) (描述事物的模板)
根据图纸盖好的房子(实际的物体) 对象(类的实例)

类 vs 对象:

(2) 1.2 为什么需要类?

不用类(用结构体,有限制):

CPP
#include <iostream>
#include <string>

struct Student {
 std::string name;
 int age;
 double score;
};

int main() {
 Student s1 = {"Alice", 20, 92.5};
 // ❌ 结构体不能包含"行为"(如"自我介绍")
 return 0;
}

用类(完整):

CPP
#include <iostream>
#include <string>

class Student {
public:
 std::string name;
 int age;
 double score;
 
 void introduce() {
 std::cout << "我叫 " << name << ",今年 " << age << " 岁。" << std::endl;
 }
};

int main() {
 Student s1;
 s1.name = "Alice";
 s1.age = 20;
 s1.introduce(); // ✅ 类可以包含"行为"
 return 0;
}


2. 类的定义*

(1) 2.1 基本语法

CPP
class ClassName {
public:
 // members (attributes and behaviors)
};

💡 重点: 类定义以分号结尾!(和结构体一样)

▶ 示例 1:定义 Student 类(难度⭐)

CPP
#include <iostream>
#include <string>

class Student {
public:
 // attributes (member variables)
 std::string name;
 int age;
 double score;

 // behaviors (member functions)
 void introduce() {
 std::cout << "我叫 " << name << ",今年 " << age << " 岁。" << std::endl;
 }
 
 void study() {
 std::cout << name << " 正在学习..." << std::endl;
 }
};

int main() {
 Student s1;
 s1.name = "Alice";
 s1.age = 20;
 s1.score = 92.5;
 
 s1.introduce();
 s1.study();
 
 return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
我叫 Alice,今年 20 岁。
Alice 正在学习...


3. 访问权限控制*

C++ 的类有三个访问权限:public(公有)、private(私有)、protected(保护)。

(1) 3.1 public vs private*

权限 类外部能访问吗? 用途
public ✅ 能 对外接口(让外界能用)
private ❌ 不能 内部实现(隐藏细节)

示例:

CPP
#include <iostream>
#include <string>

class Student {
private:
 std::string name; // private member
 int age;

public:
 // public setter and getter
 void setName(const std::string& n) {
 name = n;
 }
 
 std::string getName() {
 return name;
 }
};

int main() {
 Student s1;
 // s1.name = "Alice"; // ERROR: name is private
 s1.setName("Alice"); // OK: access via public function
 std::cout << s1.getName() << std::endl;
 return 0;
}

💡 封装思想: 把属性设为 private,通过 publicsetter/getter 访问——这样能控制访问逻辑(如检查年龄是否为负)。



4. 构造函数(Constructor)*

(1) 4.1 什么是构造函数?

构造函数是类里的一个特殊函数——创建对象时自动调用

特点 说明
函数名 和类名一样
无返回值 void 都不写
自动调用 创建对象时自动执行

▶ 示例 2:定义构造函数(难度⭐⭐)

CPP
#include <iostream>
#include <string>

class Student {
private:
 std::string name;
 int age;
 
public:
 // constructor
 Student(const std::string& n, int a) {
 name = n;
 age = a;
 std::cout << "Student 对象已创建:" << name << std::endl;
 }
 
 void introduce() {
 std::cout << "我叫 " << name << ",今年 " << age << " 岁。" << std::endl;
 }
};

int main() {
 Student s1("Alice", 20); // OK: constructor called automatically when creating object
 s1.introduce();
 
 return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
Student 对象已创建:Alice
我叫 Alice,今年 20 岁。


5. 析构函数(Destructor)*

(1) 5.1 什么是析构函数?

析构函数是类里的另一个特殊函数——对象销毁时自动调用(如函数结束时、delete 时)。

特点 说明
函数名 ~类名
无返回值 void 都不写
无参数 不能接收参数
自动调用 对象销毁时自动执行

▶ 示例 3:定义析构函数(难度⭐⭐)

CPP
#include <iostream>
#include <string>

class Student {
private:
 std::string name;
 
public:
 // constructor
 Student(const std::string& n) {
 name = n;
 std::cout << "构造函数:" << name << " 已创建" << std::endl;
 }

 // destructor
 ~Student() {
 std::cout << "析构函数:" << name << " 已销毁" << std::endl;
 }
};

int main() {
 Student s1("Alice"); // call constructor
 // when main() ends, s1 is destroyed, destructor is called
 return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
构造函数:Alice 已创建
析构函数:Alice 已销毁

💡 用途: 在析构函数里释放资源(如关闭文件、释放动态内存)。



6. this 指针*

(1) 6.1 什么是 this 指针?

this 是一个指向当前对象的指针——在成员函数里,this 可以用来访问当前对象。

▶ 示例 4:用 this 区分同名参数(难度⭐⭐)

CPP
#include <iostream>
#include <string>

class Student {
private:
 std::string name;
 
public:
 void setName(const std::string& name) { // WARNING: parameter name same as member variable
 this->name = name; // OK: use this-> to access member variable
 }

 std::string getName() {
 return this->name; // OK: this-> can be omitted (recommended to omit)
 }
};

int main() {
 Student s1;
 s1.setName("Alice");
 std::cout << s1.getName() << std::endl;
 return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
Alice

💡 提示: 如果参数名和成员变量名不一样,可以不用 this->(推荐省略,代码更简洁)。



7. 实战:简单的银行账户类*

▶ 示例 5:BankAccount 类(难度⭐⭐⭐)

CPP 📖 仅展示
#include <iostream>
#include <string>
#include <iomanip>

class BankAccount {
private:
 std::string owner;
 double balance;
 
public:
 // constructor
 BankAccount(const std::string& o, double initialBalance) {
 owner = o;
 if (initialBalance >= 0) {
 balance = initialBalance;
 } else {
 balance = 0.0;
 std::cout << "⚠️ 初始余额不能为负,已设为 0" << std::endl;
 }
 }

 // deposit
 void deposit(double amount) {
 if (amount > 0) {
 balance += amount;
 std::cout << "存款成功!+" << amount << std::endl;
 } else {
 std::cout << "⚠️ 存款金额必须大于 0" << std::endl;
 }
 }

 // withdraw
 void withdraw(double amount) {
 if (amount > 0 && amount <= balance) {
 balance -= amount;
 std::cout << "取款成功!-" << amount << std::endl;
 } else if (amount <= 0) {
 std::cout << "⚠️ 取款金额必须大于 0" << std::endl;
 } else {
 std::cout << "⚠️ 余额不足" << std::endl;
 }
 }

 // query balance
 void queryBalance() {
 std::cout << std::fixed << std::setprecision(2);
 std::cout << "账户余额:" << balance << " 元" << std::endl;
 }
};

int main() {
 BankAccount account("MOTO", 1000.0);
 
 account.queryBalance();
 account.deposit(500.0);
 account.queryBalance();
 account.withdraw(200.0);
 account.queryBalance();
 account.withdraw(2000.0); // insufficient balance
 
 return 0;
}
逻辑代码 47 行(超过 40 行限制,仅展示)

输出:

TEXT 📖 仅展示
账户余额:1000.00 元
存款成功!+500.00
账户余额:1500.00 元
取款成功!-200.00
账户余额:1300.00 元
⚠️ 余额不足

运行效果:

TEXT 📖 仅展示
账户余额:1000.00 元
存款成功!+500.00
账户余额:1500.00 元
取款成功!-200.00
账户余额:1300.00 元
⚠️ 余额不足

❓ 常见问题

Q 构造函数能重载吗?
A 能!可以定义多个构造函数(参数不同)。


📖 小节


📝 作业

  1. 基础题 (Difficulty ⭐): 定义一个 Book 类,包含书名、作者、价格三个私有成员。

  2. 提供公有的 setter 和 getter

  3. main 里创建两个 Book 对象并输出信息

  4. 进阶题 (Difficulty ⭐⭐): 定义一个 Rectangle 类,包含宽度和高度两个私有成员。

  5. 提供构造函数(带参数)

  6. 提供 double getArea()double getPerimeter() 成员函数

  7. main 里测试

  8. 挑战题 (Difficulty ⭐⭐⭐): 定义一个 Date 类,包含年、月、日三个私有成员。

  9. 提供构造函数(带参数)

  10. 提供 bool isValid() 成员函数(判断日期是否合法)

  11. 提供 void print() 成员函数(输出日期,格式:2024-02-29

  12. main 里测试

8. 🚀 下一步*

学会了类与对象的基础,接下来我们学习 构造函数进阶(第29课)—— 默认构造函数、拷贝构造函数、移动语义(C++11 新特性)!

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏