在学习 Qt 开发之前,掌握 C++ 的基础知识是至关重要的。Qt 是一个使用 C++ 编写的框架,因此理解 C++ 的面向对象编程(OOP)概念、C++11/14/17 标准特性以及 STL(标准模板库)中的常用容器,将为你在 Qt 开发中打下坚实的基础。本文将详细介绍这些内容,并结合示例代码进行说明。
面向对象编程是 C++ 的核心特性之一,主要包括以下四个基本概念:类与对象、继承、封装和多态。
示例:定义一个简单的 Car
类
#include <iostream>
#include <string>
class Car {
public:
// 属性
std::string brand;
int year;
// 构造函数
Car(std::string b, int y) : brand(b), year(y) {}
// 方法
void displayInfo() {
std::cout << "Brand: " << brand << ", Year: " << year << std::endl;
}
};
int main() {
Car myCar("Toyota", 2020); // 创建对象
myCar.displayInfo(); // 调用方法
return 0;
}
继承是创建新类的机制,新类(子类)可以继承父类的属性和方法。通过继承,可以实现代码重用和扩展。
示例:定义一个继承自 Car
的 ElectricCar
类
class ElectricCar : public Car {
public:
int batteryCapacity;
ElectricCar(std::string b, int y, int capacity)
: Car(b, y), batteryCapacity(capacity) {}
void displayInfo() {
Car::displayInfo(); // 调用父类的方法
std::cout << "Battery Capacity: " << batteryCapacity << " kWh" << std::endl;
}
};
int main() {
ElectricCar myTesla("Tesla", 2021, 75);
myTesla.displayInfo();
return 0;
}
封装是将数据和操作数据的方法组合在一起,并限制对某些数据的直接访问。通过使用访问修饰符(public、protected、private),可以控制数据的可见性。
示例:使用封装来保护属性
class BankAccount {
private:
double balance; // 私有属性
public:
BankAccount(double initialBalance) : balance(initialBalance) {}
void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
double getBalance() const {
return balance;
}
};
int main() {
BankAccount account(1000);
account.deposit(500);
std::cout << "Balance: " << account.getBalance() << std::endl;
return 0;
}
多态是指同一操作作用于不同对象时,可以表现出不同的行为。多态主要通过虚函数实现。
示例:使用虚函数实现多态
class Shape {
public:
virtual void draw() = 0; // 纯虚函数
};
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing a Circle" << std::endl;
}
};
class Square : public Shape {
public:
void draw() override {
std::cout << "Drawing a Square" << std::endl;
}
};
void render(Shape *shape) {
shape->draw(); // 调用多态方法
}
int main() {
Circle circle;
Square square;
render(&circle);
render(&square);
return 0;
}
C++11 及其后续版本引入了许多新特性,使得编程更加高效和安全。
智能指针是自动管理动态分配内存的类,包括 std::unique_ptr
和 std::shared_ptr
。
示例:使用 std::unique_ptr
#include <iostream>
#include <memory>
class Resource {
public:
Resource() { std::cout << "Resource acquired!" << std::endl; }
~Resource() { std::cout << "Resource released!" << std::endl; }
};
int main() {
std::unique_ptr<Resource> resPtr(new Resource()); // 创建智能指针
// Resource 会在 resPtr 超出作用域时自动释放
return 0;
}
Lambda 表达式提供了简洁的方式来定义匿名函数,可以用于 STL 算法中。
示例:使用 Lambda 表达式
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
std::for_each(numbers.begin(), numbers.end(), [](int n) {
std::cout << n * 2 << " "; // 输出每个元素的两倍
});
return 0;
}
C++11 引入了 std::thread
以支持多线程编程。
示例:创建和使用线程
#include <iostream>
#include <thread>
void printMessage() {
std::cout << "Hello from thread!" << std::endl;
}
int main() {
std::thread t(printMessage); // 创建线程
t.join(); // 等待线程完成
return 0;
}
STL 是 C++ 标准模板库,提供了一系列算法和数据结构。以下是常用的容器:
std::vector
是动态数组,可以自动调整大小。
示例:使用 std::vector
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
vec.push_back(6); // 添加元素
for (int n : vec) {
std::cout << n << " "; // 输出元素
}
return 0;
}
std::map
是键值对的集合,按照键的顺序自动排序。
示例:使用 std::map
#include <iostream>
#include <map>
int main() {
std::map<std::string, int> ageMap;
ageMap["Alice"] = 30;
ageMap["Bob"] = 25;
for (const auto& pair : ageMap) {
std::cout << pair.first << ": " << pair.second << std::endl; // 输出键值对
}
return 0;
}
std::set
是不重复元素的集合,自动排序。
示例:使用 std::set
#include <iostream>
#include <set>
int main() {
std::set<int> numSet = {1, 2, 2, 3, 4}; // 重复元素会被忽略
for (int n : numSet) {
std::cout << n << " "; // 输出唯一元素
}
return 0;
}
通过本文,我们详细探讨了 C++ 基础知识,包括面向对象编程的核心概念、C++11/14/17 标准特性以及 STL 中的常用容器。掌握这些知识,不仅能够帮助你更好地理解 Qt 的工作原理,也能够提升你在 C++ 编程中的能力和效率。希望这些示例代码能为你的学习提供实用的参考!