C++后端编程 构建高性能后端的数据库、API 与 Web 服务器 2 C++复习与要点
C++在后端编程中的潜力
C++ 语法
int num_users = 500;
std::string user_name = "Alice";
bool is_user_online = false;
if (user_age >= 18) {
std::cout << "Registration successful!";
} else {
std::cout << "Sorry, you must be at least 18 years old to register.";
}
函数
void update_user_age(std::string user, int new_age) {
// Code to update a user's age in the database
}
int calculate_average_age() {
// Code to calculate the average age of all users
}
类与对象
class User {
public:
std::string name;
int age;
User(std::string user_name, int user_age) {
name = user_name;
age = user_age;
}
void update_age(int new_age) {
age = new_age;
}
};
STL 容器
std::vector users; // 用户列表
std::map user_id_to_user; // 从用户 ID 到用户对象的映射
错误处理
try {
User user = get_user_from_database(user_id);
} catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << std::endl;
// 处理错误(例如:向客户端返回错误响应)
}
这些只是 C++语法的基础知识及其在后端编程中的潜在应用。 它们是编写后端应用程序 C++代码的基本构建模块。 随着学习的深入,我们将探索更高级的主题,包括多线程、网络编程和数据库操作,届时 C++的强大功能将真正得以展现。
C++语义
int a = 5;
int b = a; // b 是 a 的副本,而非引用
b += 5; // 修改 b 不会影响 a
引用语义
int a = 5;
int& ref_to_a = a; // ref_to_a is a reference to a
ref_to_a += 5; // changing ref_to_a also changes a
面向对象编程(OOP)
class User {
public:
std::string name;
// ...
void sendMessage(const std::string& message);
};
资源获取即初始化(RAII)
class DatabaseConnection {
public:
DatabaseConnection(const std::string& dsn) {
// acquire the connection
}
~DatabaseConnection() {
// release the connection
}
};
模板与泛型编程
template
T max(T a, T b) {
return (a > b) ? a : b;
}
std::thread worker(do_some_work);
// ...
worker.join();
try {
// risky operation
} catch (const std::exception& e) {
// handle error
}
int* dynamic_array = new int[100];
// ...
delete[] dynamic_array;
std::vector vec1 = {1, 2, 3};
std::vector vec2 = std::move(vec1); // 将数据从 vec1 移动至 vec2
auto add = [](int a, int b) -> int { return a + b; };
int sum = add(5, 7);
std::shared_ptr ptr(new int(10)); // 当 ptr 离开作用域时,内存将被自动释放
auto num = 5; // num 的类型为 int
auto str = "Hello, World!"; // str 是 const char* 类型
std::vector nums = {4, 2, 5, 1, 3};
std::sort(nums.begin(), nums.end()); // 对向量进行排序
C++数据结构
int arr[5] = {1, 2, 3, 4, 5};
std::string greeting = "Hello, World!";
在后端编程中,字符串无处不在——它们用于表示文本数据、操作和存储数据库信息、处理用户输入、生成 HTML 响应等。
std::list mylist = {7, 5, 16, 8};
在后端开发中,当需要频繁执行列表元素的插入和删除操作且元素顺序很重要时,链表会非常有用。 但由于无法通过索引直接访问元素,链表的元素访问速度不如数组或向量快。
std::vector myvector = {1, 2, 3, 4, 5};
向量在后端开发中具有极高的通用性和实用性。 它们可用于存储和操作数据集合,得益于动态调整大小的特性,非常适合在编译时无法确定数据量的场景。 在各种后端任务中都大有用武之地,比如存储处理用户数据、保存数据库查询结果,或缓冲来自网络流的数据。
C++中的面向对象编程
class BlogPost {
public:
BlogPost(const std::string& title, const std::string& author)
: title(title), author(author) {}
std::string getTitle() const { return title; }
std::string getAuthor() const { return author; }
private:
std::string title;
std::string author;
// More properties...
};
对象是类的实例。 创建对象就像声明特定类型的变量:
BlogPost post("我的第一篇博文", "John Doe");
class User {
public:
User(const std::string& username) : username(username) {}
std::string getUsername() const { return username; }
// Other User methods...
private:
std::string username;
};
class AdminUser : public User {
public:
AdminUser(const std::string& username)
: User(username) {}
void performAdminTask() { /*...*/ }
};
class Database {
public:
virtual void connect() = 0;
virtual void query(const std::string& sql) = 0;
// Other Database methods...
};
class MongoDB : public Database {
public:
void connect() override { /* MongoDB-specific connection code */ }
void query(const std::string& sql) override { /* MongoDB-specific query code */ }
};
class PostgreSQL : public Database {
public:
void connect() override { /* PostgreSQL-specific connection code */ }
void query(const std::string& sql) override { /* PostgreSQL-specific query code */ }
};
面向对象编程(OOP)原则对于设计和组织优质后端代码至关重要。 它们让我们能够以现实世界实体及其交互的方式来思考代码,使代码更易于理解和维护。 通过围绕对象构建代码并运用封装、继承和多态性原则,我们可以创建健壮且可维护的后端系统。
标准模板库
std::vector vec = {1, 2, 3, 4, 5};
std::map map = {{"apple", 5}, {"orange", 10}};
std::unordered_map unordered_map = {{"apple", 5}, {"orange", 10}};
std::set set = {1, 2, 3, 4, 5};
std::unordered_set unordered_set = {1, 2, 3, 4, 5};
std::vector vec = {5, 3, 4, 1, 2};
std::sort(vec.begin(), vec.end());
std::vector vec = {5, 3, 4, 1, 2};
auto it = std::find(vec.begin(), vec.end(), 3);
class BlogPost {
public:
BlogPost(const std::string& title) : title(title) {}
std::string getTitle() const { return title; }
private:
std::string title;
};
class CompareBlogPosts {
public:
bool operator()(const BlogPost& a, const BlogPost& b) const {
return a.getTitle() < b.getTitle();
}
};
std::vector posts = {BlogPost("Post 2"), BlogPost("Post 1")};
std::sort(posts.begin(), posts.end(), CompareBlogPosts());
这种设计模式能让您编写出易于复用且适应各种场景的代码,这正是后端开发中经常需要的。STL 是 C++不可或缺的组成部分,每位后端开发人员都应熟悉它。
错误处理
BlogPost getBlogPost(int id) {
// Fetch the BlogPost from the database...
if (/* failed to fetch the BlogPost */) {
throw std::runtime_error("Failed to fetch the blog post from the database");
}
// Return the fetched BlogPost...
}
try {
BlogPost post = getBlogPost(1);
// Process the fetched BlogPost...
} catch (const std::exception& e) {
// Log the error message and handle the error condition...
std::cerr << "An error occurred: " << e.what() << std::endl;
}
class DatabaseException : public std::runtime_error {
public:
DatabaseException(const std::string& message)
: std::runtime_error(message) {}
};
BlogPost getBlogPost(int id) {
// Fetch the BlogPost from the database...
if (/* failed to fetch the BlogPost */) {
throw DatabaseException("Failed to fetch the blog post from the database");
}
// Return the fetched BlogPost...
}
多线程
#include
void doWork() {
// Code for the new thread to execute...
}
int main() {
std::thread worker(doWork);
// ... other code ...
// Wait for the worker thread to finish before exiting the main thread.
worker.join();
}
#include
#include
std::mutex mtx;
int sharedData = 0;
void incrementData() {
std::lock_guard lock(mtx);
++sharedData;
}
int main() {
std::thread t1(incrementData);
std::thread t2(incrementData);
t1.join();
t2.join();
// At this point, sharedData is guaranteed to be 2.
}
#include
#include
void handleRequest(Request req) {
// Process the request...
}
int main() {
std::vector workers;
while (true) {
Request req = getIncomingRequest();
workers.push_back(std::thread(handleRequest, req));
}
// In a real application, you'd need to join the threads at some point.
}
在上述示例程序中,每个传入请求都会启动一个新线程来运行 handleRequest 函数。 这使得服务器能够并发处理多个请求。

