Appearance
C++ 数据抽象
数据抽象是指只向外界提供必要的信息,而隐藏具体的实现细节。它是面向对象编程的核心概念之一,通过抽象类和接口来实现。
1. 数据抽象的基本概念
数据抽象依赖于两个关键概念:
- 接口:提供对对象进行操作的函数集合
- 实现:接口的具体实现细节
1.1 示例
cpp
#include <iostream>
class Calculator {
public:
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int multiply(int a, int b) {
return a * b;
}
int divide(int a, int b) {
return a / b;
}
};
int main() {
Calculator calculator;
std::cout << "10 + 20 = " << calculator.add(10, 20) << std::endl;
std::cout << "10 - 20 = " << calculator.subtract(10, 20) << std::endl;
std::cout << "10 * 20 = " << calculator.multiply(10, 20) << std::endl;
std::cout << "20 / 10 = " << calculator.divide(20, 10) << std::endl;
return 0;
}2. 访问修饰符
访问修饰符是实现数据抽象的重要工具。
2.1 private 成员
private成员只能在类内部被访问,外部无法直接访问。
cpp
#include <iostream>
class BankAccount {
private:
double balance;
public:
BankAccount(double initial_balance) : balance(initial_balance) {}
void deposit(double amount) {
balance += amount;
}
void withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
}
}
double get_balance() {
return balance;
}
};
int main() {
BankAccount account(1000.0);
account.deposit(500.0);
account.withdraw(200.0);
std::cout << "余额: " << account.get_balance() << std::endl;
return 0;
}2.2 public 成员
public成员可以在任何地方被访问。
cpp
#include <iostream>
class Point {
public:
int x;
int y;
Point(int x, int y) : x(x), y(y) {}
void print() {
std::cout << "(" << x << ", " << y << ")" << std::endl;
}
};
int main() {
Point point(10, 20);
point.x = 30;
point.y = 40;
point.print();
return 0;
}3. 抽象类
抽象类是包含至少一个纯虚函数的类,它不能被实例化,只能被继承。
3.1 抽象类的基本用法
cpp
#include <iostream>
class Shape {
public:
virtual double area() = 0;
virtual double perimeter() = 0;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double radius) : radius(radius) {}
double area() override {
return 3.14159 * radius * radius;
}
double perimeter() override {
return 2 * 3.14159 * radius;
}
};
class Rectangle : public Shape {
private:
double width;
double height;
public:
Rectangle(double width, double height) : width(width), height(height) {}
double area() override {
return width * height;
}
double perimeter() override {
return 2 * (width + height);
}
};
int main() {
Shape* shape;
Circle circle(5.0);
Rectangle rectangle(4.0, 6.0);
shape = &circle;
std::cout << "圆的面积: " << shape->area() << std::endl;
std::cout << "圆的周长: " << shape->perimeter() << std::endl;
shape = &rectangle;
std::cout << "矩形的面积: " << shape->area() << std::endl;
std::cout << "矩形的周长: " << shape->perimeter() << std::endl;
return 0;
}4. 数据抽象的好处
4.1 隐藏实现细节
cpp
#include <iostream>
class Stack {
private:
int* data;
int top;
int capacity;
public:
Stack(int size) : capacity(size), top(-1) {
data = new int[capacity];
}
~Stack() {
delete[] data;
}
void push(int value) {
if (top == capacity - 1) {
std::cout << "栈已满" << std::endl;
return;
}
data[++top] = value;
}
int pop() {
if (top == -1) {
std::cout << "栈为空" << std::endl;
return -1;
}
return data[top--];
}
bool is_empty() {
return top == -1;
}
bool is_full() {
return top == capacity - 1;
}
};
int main() {
Stack stack(5);
stack.push(10);
stack.push(20);
stack.push(30);
while (!stack.is_empty()) {
std::cout << stack.pop() << " ";
}
std::cout << std::endl;
return 0;
}4.2 提高代码的可维护性
cpp
#include <iostream>
class Employee {
private:
std::string name;
double salary;
public:
Employee(std::string name, double salary) : name(name), salary(salary) {}
void set_name(std::string name) {
this->name = name;
}
std::string get_name() {
return name;
}
void set_salary(double salary) {
if (salary >= 0) {
this->salary = salary;
}
}
double get_salary() {
return salary;
}
void display() {
std::cout << "姓名: " << name << std::endl;
std::cout << "工资: " << salary << std::endl;
}
};
int main() {
Employee employee("张三", 10000.0);
employee.display();
employee.set_name("李四");
employee.set_salary(12000.0);
employee.display();
return 0;
}5. 示例:综合运用
现在,让我们看一个综合运用数据抽象特性的例子:
cpp
#include <iostream>
#include <string>
class Database {
private:
struct Node {
std::string key;
std::string value;
Node* next;
Node(std::string key, std::string value)
: key(key), value(value), next(nullptr) {}
};
Node* head;
public:
Database() : head(nullptr) {}
~Database() {
Node* current = head;
while (current != nullptr) {
Node* next = current->next;
delete current;
current = next;
}
}
void insert(std::string key, std::string value) {
Node* new_node = new Node(key, value);
if (head == nullptr) {
head = new_node;
} else {
Node* current = head;
while (current->next != nullptr) {
current = current->next;
}
current->next = new_node;
}
}
std::string get(std::string key) {
Node* current = head;
while (current != nullptr) {
if (current->key == key) {
return current->value;
}
current = current->next;
}
return "";
}
void update(std::string key, std::string value) {
Node* current = head;
while (current != nullptr) {
if (current->key == key) {
current->value = value;
return;
}
current = current->next;
}
}
void remove(std::string key) {
if (head == nullptr) {
return;
}
if (head->key == key) {
Node* temp = head;
head = head->next;
delete temp;
return;
}
Node* current = head;
while (current->next != nullptr) {
if (current->next->key == key) {
Node* temp = current->next;
current->next = temp->next;
delete temp;
return;
}
current = current->next;
}
}
void display() {
Node* current = head;
while (current != nullptr) {
std::cout << current->key << ": " << current->value << std::endl;
current = current->next;
}
}
};
int main() {
Database db;
db.insert("name", "张三");
db.insert("age", "20");
db.insert("city", "北京");
std::cout << "数据库内容:" << std::endl;
db.display();
std::cout << std::endl;
std::cout << "获取 name: " << db.get("name") << std::endl;
std::cout << "获取 age: " << db.get("age") << std::endl;
std::cout << std::endl;
db.update("age", "21");
std::cout << "更新 age 后:" << std::endl;
db.display();
std::cout << std::endl;
db.remove("city");
std::cout << "删除 city 后:" << std::endl;
db.display();
return 0;
}小结
C++ 数据抽象包括:
数据抽象的基本概念:
- 接口:提供对对象进行操作的函数集合
- 实现:接口的具体实现细节
访问修饰符:
private成员:只能在类内部被访问public成员:可以在任何地方被访问
抽象类:
- 包含至少一个纯虚函数的类
- 不能被实例化,只能被继承
数据抽象的好处:
- 隐藏实现细节
- 提高代码的可维护性
- 降低代码的耦合度
关键概念:
- 数据抽象:只向外界提供必要的信息,而隐藏具体的实现细节
- 接口:提供对对象进行操作的函数集合
- 实现:接口的具体实现细节
- 抽象类:包含至少一个纯虚函数的类
- 访问修饰符:控制类成员的访问权限
掌握数据抽象是 C++ 面向对象编程的重要基础,在后续章节中,我们将学习 C++ 的数据封装。