一、面向过程与面向对象编程
1. 什么是面向过程编程?
面向过程编程(Procedural Programming)是一种以过程(或函数)为中心的编程范式。程序被视为一系列按顺序执行的步骤,主要通过函数对数据进行操作
特点:
- 执行顺序明确:程序按照代码书写的顺序执行
- 侧重算法:重视具体的操作步骤和实现流程
- 代码重用性低:相似的功能需要重复编写代码
代码示例:计算数组元素的平均值
#include <iostream>
using namespace std;
int main() {
const int SIZE = 5;
int numbers[SIZE] = {5, 10, 15, 20, 25};
int sum = 0;
for (int i = 0; i < SIZE; ++i) {
sum += numbers[i];
}
double average = static_cast<double>(sum) / SIZE;
cout << "平均值是:" << average << endl;
return 0;
}
2. 什么是面向对象编程?
面向对象编程(Object-Oriented Programming,OOP)是一种以对象为中心的编程范式。它将数据和操作数据的函数封装在一起,称为对象。程序被设计为一组相互交互的对象
特点:
- 封装(Encapsulation):将数据和相关操作封装在对象内部,保护数据不被外部直接访问
- 继承(Inheritance):可以从已有的类创建新的类,重用代码
- 多态(Polymorphism):不同对象可以以统一的方式被使用
代码示例:定义一个计算平均值的类
#include <iostream>
#include <vector>
using namespace std;
class Statistics {
private:
vector<int> data;
public:
void addData(int value) {
data.push_back(value);
}
double calculateAverage() {
if (data.empty()) return 0.0;
int sum = 0;
for (int val : data) {
sum += val;
}
return static_cast<double>(sum) / data.size();
}
};
int main() {
Statistics stats;
stats.addData(5);
stats.addData(10);
stats.addData(15);
stats.addData(20);
stats.addData(25);
cout << "平均值是:" << stats.calculateAverage() << endl;
return 0;
}
3. 比较一下:
二、引入与定义
1. 为什么需要类
面向对象编程中,类(Class)是创建对象的蓝图或模板。它定义了对象的属性(数据)和方法(行为)。通过类,可以创建多个具有相同属性和行为的对象
2. 类的定义
在C++中,类的定义使用class
关键字
语法格式:
class 类名 {
访问限定符:
// 属性(成员变量)
// 方法(成员函数)
};
代码示例:定义一个表示学生信息的类
#include <iostream>
using namespace std;
class Student {
public:
// 属性
string name;
int age;
double score;
// 方法
void introduce() {
cout << "姓名:" << name << ", 年龄:" << age << ", 分数:" << score << endl;
}
};
3. 类的成员
- 成员变量(属性):保存对象的状态或数据,如
name
、age
、score
- 成员函数(方法):定义对象的行为或操作,如
introduce()
三、访问限定符与封装
1. 访问限定符(入门篇也有)
访问限定符用于控制类的成员变量和成员函数的可见性。C++提供了三个访问限定符:
- public(公有):公共成员,可以被类的内部和外部访问
- private(私有):私有成员,只能被类的内部访问,外部不能直接访问
- protected(受保护):受保护成员,可以被类的内部和子类访问,但无法被外部直接访问
2. 封装(Encapsulation)
封装是面向对象的基本特性之一,它将数据(属性)和操作数据的函数(方法)包装在一起,并对数据的访问进行控制,保护对象的完整性
3. 使用private进行封装
将类的成员变量设置为private
,通过public
的成员函数(如set
和get
方法)来访问和修改数据
代码示例:
#include <iostream>
using namespace std;
class BankAccount {
private:
string accountNumber;
double balance;
public:
// 构造函数
BankAccount(string accNum, double bal) {
accountNumber = accNum;
balance = bal;
}
// 存款
void deposit(double amount) {
if (amount > 0) {
balance += amount;
cout << "存款成功,当前余额:" << balance << endl;
} else {
cout << "存款金额必须大于0。" << endl;
}
}
// 取款
void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
cout << "取款成功,当前余额:" << balance << endl;
} else {
cout << "取款金额不合法。" << endl;
}
}
// 查询余额
double getBalance() {
return balance;
}
};
int main() {
BankAccount account("1234567890", 1000.0);
account.deposit(500.0);
account.withdraw(200.0);
cout << "最终余额:" << account.getBalance() << endl;
// account.balance = 5000.0; // 错误,无法访问private成员
return 0;
}
4. 访问限定符的使用注意
- 默认访问级别:如果未指定访问限定符,
class
中的成员默认是private
;struct
中的成员默认是public
- 建议:将成员变量设置为
private
或protected
,通过public
成员函数访问,增强封装性
四、类的作用域
1. 类的成员作用域
- 类的内部:可以访问所有成员,包括
private
、protected
和public
- 派生类(子类):可以访问基类的
protected
和public
成员,不能访问private
成员 - 类的外部:只能访问对象的
public
成员,不能访问private
和protected
成员
2. 作用域解析符::
作用域解析符::
用于指定变量或函数所属的作用域
代码示例:
#include <iostream>
using namespace std;
class Circle {
private:
double radius;
public:
Circle(double r);
double getArea();
};
// 构造函数的实现
Circle::Circle(double r) {
radius = r;
}
// 成员函数的实现
double Circle::getArea() {
return 3.14159 * radius * radius;
}
int main() {
Circle c(5.0);
cout << "圆的面积是:" << c.getArea() << endl;
return 0;
}
五、对象的实例化
1. 什么是实例化?
实例化(Instantiation)是根据类创建对象的过程。对象是类的具体实例,拥有类定义的属性和方法
2. 实例化对象的方法
- 方式一:直接声明对象
ClassName objectName;
- 方式二:使用
new
关键字在堆上创建对象,返回指针
ClassName* objectPtr = new ClassName();
代码实例:方式一
#include <iostream>
using namespace std;
class Rectangle {
public:
double width;
double height;
double getArea() {
return width * height;
}
};
int main() {
Rectangle rect; // 实例化对象
rect.width = 10.0;
rect.height = 5.0;
cout << "矩形的面积是:" << rect.getArea() << endl;
return 0;
}
代码示例:方式二
#include <iostream>
using namespace std;
class Rectangle {
public:
double width;
double height;
Rectangle(double w, double h) {
width = w;
height = h;
}
double getArea() {
return width * height;
}
};
int main() {
Rectangle* rectPtr = new Rectangle(10.0, 5.0); // 使用指针
cout << "矩形的面积是:" << rectPtr->getArea() << endl;
delete rectPtr; // 释放内存
return 0;
}
六、对象大小的计算
1. 对象的内存布局
对象的大小与其成员变量有关(静态成员除外)。成员函数存在于代码段,多个对象共享同一份函数代码,因此不计入对象大小
2. 计算对象大小的方式
使用sizeof
操作符可以获取对象或类的大小
语法:
sizeof(object);
sizeof(ClassName);
代码示例:
#include <iostream>
using namespace std;
class Example {
char a; // 1字节
int b; // 4字节
double c; // 8字节
public:
void func() {}
};
int main() {
Example e;
cout << "对象e的大小:" << sizeof(e) << " 字节" << endl;
cout << "类Example的大小:" << sizeof(Example) << " 字节" << endl;
return 0;
}
注意:
- 由于内存对齐,实际大小可能大于成员变量大小之和
- 成员函数不影响对象大小
4. 分析内存对齐
#include <iostream>
using namespace std;
class Alignment {
char a; // 1字节
// padding 3字节,使下一个int在4字节边界上
int b; // 4字节
};
int main() {
cout << "类Alignment的大小:" << sizeof(Alignment) << " 字节" << endl;
return 0;
}
解释:
char a
占1字节,为了对齐,下一个int
从第4字节开始,需要填充3字节- 总大小为1 + 3(填充) + 4 = 8字节
七、this
指针
1. 什么是this
指针?
this
指针是C++中类的成员函数内的一个隐含指针,指向调用该成员函数的对象本身。通过this
指针,可以在成员函数中访问对象的成员变量和其他成员函数
2. this
指针的特点
- 隐式存在:不需要显式声明,可直接使用
- 指向当前对象:用于区分成员变量和形参或局部变量
- 常用在返回对象自身或链式调用中
代码示例
1.区分成员变量和形参
#include <iostream>
using namespace std;
class Person {
private:
string name;
int age;
public:
void setName(string name) {
this->name = name; // 使用this指针
}
void setAge(int age) {
this->age = age;
}
void display() {
cout << "姓名:" << name << ", 年龄:" << age << endl;
}
};
int main() {
Person person;
person.setName("Bob");
person.setAge(25);
person.display();
return 0;
}
2.返回对象自身,实现链式调用
#include <iostream>
using namespace std;
class Calculator {
private:
int result;
public:
Calculator() : result(0) {}
Calculator& add(int value) {
result += value;
return *this;
}
Calculator& subtract(int value) {
result -= value;
return *this;
}
Calculator& multiply(int value) {
result *= value;
return *this;
}
int getResult() {
return result;
}
};
int main() {
Calculator calc;
int finalResult = calc.add(10).subtract(5).multiply(3).getResult();
cout << "计算结果是:" << finalResult << endl;
return 0;
}
3. const成员函数中的this
指针
在const
成员函数中,this
指针的类型为const ClassName*
,表示不能修改对象的成员变量
#include <iostream>
using namespace std;
class Sample {
private:
int value;
public:
Sample(int v) : value(v) {}
void display() const {
// this指针的类型为 const Sample*
cout << "值是:" << value << endl;
// this->value = 10; // 错误,不能修改成员变量
}
};
int main() {
Sample s(5);
s.display();
return 0;
}