本文深入探讨了C++高级语法中的多种关键概念,包括类和对象的封装、继承与多态,以及模板的高级应用。此外,文章还介绍了C++中的异常处理机制和STL标准模板库的使用。通过丰富的示例代码和详细的案例分析,读者可以更好地理解和掌握C++高级语法。
深入理解类和对象 封装、继承与多态的深入讲解封装
封装是面向对象编程的核心概念之一,它通过将数据和操作这些数据的方法绑定在一起,并对外提供统一的接口,来实现对数据的访问和修改的控制。在C++中,我们可以通过类来实现封装。
继承
继承是指一个类可以继承另一个类的属性和方法,从而实现代码的重用。子类可以继承父类的成员变量和成员函数,并且可以扩展或重写父类的方法。
多态
多态是指同一个接口可以有多种实现方式,即在运行时根据对象的实际类型调用相应的方法。这可以通过虚函数和抽象类来实现。
示例代码
#include <iostream>
class Base {
public:
virtual void show() {
std::cout << "Base show" << std::endl;
}
};
class Derived : public Base {
public:
void show() override {
std::cout << "Derived show" << std::endl;
}
};
int main() {
Base* base = new Derived();
base->show();
delete base;
return 0;
}
构造函数与析构函数的使用
构造函数
构造函数是在创建对象时自动被调用的特殊成员函数,用于初始化对象的状态。构造函数可以有多个,包括默认构造函数、拷贝构造函数等。
析构函数
析构函数是在对象生命周期结束时自动被调用的特殊成员函数,用于释放对象占用的资源。析构函数没有参数,也没有返回值。
示例代码
#include <iostream>
class MyClass {
public:
MyClass() {
std::cout << "Default Constructor" << std::endl;
}
MyClass(const MyClass& other) {
std::cout << "Copy Constructor" << std::endl;
}
~MyClass() {
std::cout << "Destructor" << std::endl;
}
};
int main() {
MyClass obj1;
MyClass obj2(obj1);
return 0;
}
静态成员变量和成员函数介绍
静态成员变量
静态成员变量属于类,而不是对象。静态成员变量在类的所有对象之间共享,只存在一份拷贝。
静态成员函数
静态成员函数属于类,而不是对象。静态成员函数可以访问静态成员变量,但不能访问非静态成员变量。静态成员函数没有this指针。
示例代码
#include <iostream>
class MyClass {
public:
static int count;
MyClass() {
count++;
}
static void getCount() {
std::cout << "Count: " << count << std::endl;
}
};
int MyClass::count = 0;
int main() {
MyClass obj1, obj2;
MyClass::getCount();
return 0;
}
静态成员变量应用案例
#include <iostream>
class MyClass {
public:
static int count;
MyClass() {
count++;
}
static void getCount() {
std::cout << "Count: " << count << std::endl;
}
};
int MyClass::count = 0;
int main() {
MyClass obj1, obj2;
MyClass::getCount(); // 输出 Count: 2
return 0;
}
模板的高级应用
模板类与模板函数的讲解
模板类
模板类是一种通用的类模板,可以接受一个或多个类型参数。模板类可以用于创建不同类型的具体类,从而实现代码的复用。
模板函数
模板函数是一种通用的函数模板,可以接受一个或多个类型参数。模板函数可以用于处理不同类型的数据,从而实现代码的复用。
示例代码
#include <iostream>
// 模板类
template <typename T>
class MyTemplateClass {
public:
T value;
MyTemplateClass(T val) : value(val) {}
void display() {
std::cout << "Value: " << value << std::endl;
}
};
// 模板函数
template <typename T>
void printValue(T val) {
std::cout << "Value: " << val << std::endl;
}
int main() {
MyTemplateClass<int> obj1(5);
obj1.display();
MyTemplateClass<std::string> obj2("Hello");
obj2.display();
printValue(10);
printValue("Hello");
return 0;
}
模板特化与偏特化的使用
模板特化
模板特化是指为特定类型定义特殊的模板实现。模板特化可以用于处理特定类型的特殊情况。
模板偏特化
模板偏特化是指为部分参数类型定义特殊的模板实现。模板偏特化可以用于处理部分参数类型的特殊情况。
示例代码
#include <iostream>
// 模板类
template <typename T>
class MyTemplateClass {
public:
T value;
MyTemplateClass(T val) : value(val) {}
void display() {
std::cout << "Value: " << value << std::endl;
}
};
// 模板特化
template <>
class MyTemplateClass<std::string> {
public:
std::string value;
MyTemplateClass(std::string val) : value(val) {}
void display() {
std::cout << "Specialized String: " << value << std::endl;
}
};
// 模板偏特化
template <typename T>
class MyTemplateClass<std::vector<T>> {
public:
std::vector<T> value;
MyTemplateClass(std::vector<T> val) : value(val) {}
void display() {
std::cout << "Specialized Vector: ";
for (const auto& item : value) {
std::cout << item << " ";
}
std::cout << std::endl;
}
};
int main() {
MyTemplateClass<int> obj1(5);
obj1.display();
MyTemplateClass<std::string> obj2("Hello");
obj2.display();
MyTemplateClass<std::vector<int>> obj3({1, 2, 3});
obj3.display();
return 0;
}
复杂模板特化案例
#include <iostream>
// 模板类
template <typename T>
class MyTemplateClass {
public:
T value;
MyTemplateClass(T val) : value(val) {}
void display() {
std::cout << "Value: " << value << std::endl;
}
};
// 复杂模板特化
template <>
class MyTemplateClass<std::pair<int, std::string>> {
public:
std::pair<int, std::string> value;
MyTemplateClass(std::pair<int, std::string> val) : value(val) {}
void display() {
std::cout << "Specialized Pair: " << value.first << " - " << value.second << std::endl;
}
};
int main() {
MyTemplateClass<std::pair<int, std::string>> obj4(std::make_pair(1, "Hello"));
obj4.display();
return 0;
}
异常处理机制
异常的基本概念
异常处理机制是C++中用于处理程序运行时发生的错误的一种机制。当程序中发生错误时,可以抛出异常对象,并通过捕获异常对象来处理错误。
throw和try-catch语句的使用throw
throw
关键字用于抛出一个异常对象。当程序中发生错误时,可以使用throw
关键字抛出一个异常对象。
try-catch
try-catch
语句用于捕获和处理异常。try
块中包含可能发生错误的代码,catch
块中包含处理异常的代码。
示例代码
#include <iostream>
void divide(int a, int b) {
if (b == 0) {
throw std::runtime_error("Division by zero");
}
std::cout << "Result: " << a / b << std::endl;
}
int main() {
try {
divide(10, 0);
} catch (const std::runtime_error& e) {
std::cout << "Caught exception: " << e.what() << std::endl;
}
try {
divide(10, 2);
} catch (const std::runtime_error& e) {
std::cout << "Caught exception: " << e.what() << std::endl;
}
return 0;
}
自定义异常类的创建
自定义异常类
可以创建自己的异常类来抛出和捕获特定类型的异常。自定义异常类通常继承自std::exception
类。
示例代码
#include <iostream>
#include <exception>
class CustomException : public std::exception {
public:
const char* what() const throw() {
return "Custom Exception";
}
};
void throwCustomException() {
throw CustomException();
}
int main() {
try {
throwCustomException();
} catch (const CustomException& e) {
std::cout << "Caught custom exception: " << e.what() << std::endl;
}
return 0;
}
复杂自定义异常类
#include <iostream>
#include <exception>
class ComplexException : public std::exception {
public:
const char* what() const throw() {
return "Complex Exception";
}
};
void throwComplexException() {
throw ComplexException();
}
int main() {
try {
throwComplexException();
} catch (const std::exception& e) {
std::cout << "Caught complex exception: " << e.what() << std::endl;
}
return 0;
}
STL标准模板库
STL容器的使用
STL容器是一种通用的数据结构,可以用于存储和操作不同类型的数据。STL容器包括顺序容器(如vector、list、deque)和关联容器(如set、map、unordered_set、unordered_map)。
示例代码
#include <iostream>
#include <vector>
#include <list>
#include <unordered_map>
int main() {
// vector
std::vector<int> vec = {1, 2, 3};
for (int i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
// list
std::list<int> lst = {4, 5, 6};
for (int i : lst) {
std::cout << i << " ";
}
std::cout << std::endl;
// unordered_map
std::unordered_map<std::string, int> umap = {{"one", 1}, {"two", 2}};
for (const auto& kv : umap) {
std::cout << kv.first << ": " << kv.second << std::endl;
}
return 0;
}
STL算法的介绍
STL算法是一组通用的算法,用于对容器中的数据进行操作。STL算法包括迭代器算法、排序算法、查找算法等。
示例代码
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {3, 1, 4, 1, 5, 9};
// 排序
std::sort(vec.begin(), vec.end());
for (int i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
// 查找
auto it = std::find(vec.begin(), vec.end(), 1);
if (it != vec.end()) {
std::cout << "Found: " << *it << std::endl;
}
return 0;
}
迭代器的深入理解
迭代器是一种用于遍历容器中的数据的对象。迭代器可以像指针一样使用,可以用于访问和修改容器中的元素。
示例代码
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 使用迭代器遍历
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 修改元素
std::vector<int>::iterator it = vec.begin();
*it = 0;
for (int i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
迭代器的应用案例
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 使用迭代器遍历并修改元素
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
*it *= 2;
}
for (int i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
C++11新特性介绍
auto关键字的应用
auto
关键字是一种类型推导机制,可以在声明变量时自动推导变量的类型。auto
关键字可以用于简化代码的编写。
示例代码
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 使用auto推导类型
auto it = vec.begin();
std::cout << "Type of it: " << typeid(it).name() << std::endl;
// 使用auto推导返回类型
auto sum = [](int a, int b) { return a + b; };
std::cout << "Sum: " << sum(1, 2) << std::endl;
return 0;
}
lambda表达式入门
lambda表达式是一种匿名函数,可以在代码中临时定义一个函数。lambda表达式可以用于简化代码的编写。
示例代码
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {3, 1, 4, 1, 5, 9};
// 使用lambda表达式排序
std::sort(vec.begin(), vec.end(), [](int a, int b) { return a < b; });
for (int i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
// 使用lambda表达式查找
auto it = std::find_if(vec.begin(), vec.end(), [](int i) { return i % 2 == 0; });
if (it != vec.end()) {
std::cout << "Found even number: " << *it << std::endl;
}
return 0;
}
复杂lambda表达式
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {3, 1, 4, 1, 5, 9};
// 使用lambda表达式排序并输出
std::sort(vec.begin(), vec.end(), [](int a, int b) { return a < b; });
std::for_each(vec.begin(), vec.end(), [](int i) { std::cout << i << " "; });
std::cout << std::endl;
return 0;
}
强制类型转换与类型别名
强制类型转换是一种显式将一个类型转换为另一个类型的方法。类型别名是一种为已存在的类型定义一个新的名字的方法。
示例代码
#include <iostream>
#include <type_traits>
int main() {
int a = 10;
double b = static_cast<double>(a);
std::cout << "a: " << a << ", b: " << b << std::endl;
// 类型别名
typedef std::vector<int> IntVector;
IntVector vec = {1, 2, 3, 4, 5};
for (int i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
智能指针的使用
std::unique_ptr和std::shared_ptr的区别
std::unique_ptr
std::unique_ptr
是一种独占所有权的智能指针,表示一个对象只能被一个智能指针持有。当std::unique_ptr
对象生命周期结束时,它会自动释放所持有的资源。
std::shared_ptr
std::shared_ptr
是一种共享所有权的智能指针,表示多个智能指针可以共享一个对象的所有权。当std::shared_ptr
对象生命周期结束时,它会自动释放所持有的资源,当最后一个std::shared_ptr
对象生命周期结束时,它会自动释放所持有的资源。
示例代码
#include <iostream>
#include <memory>
int main() {
// unique_ptr
std::unique_ptr<int> uptr(new int(10));
*uptr = 20;
std::cout << "unique_ptr value: " << *uptr << std::endl;
// shared_ptr
std::shared_ptr<int> sptr(new int(30));
*sptr = 40;
std::cout << "shared_ptr value: " << *sptr << std::endl;
return 0;
}
智能指针的内存管理机制
智能指针通过引用计数来管理内存。当智能指针的引用计数为0时,它会自动释放所持有的资源。
示例代码
#include <iostream>
#include <memory>
int main() {
std::shared_ptr<int> sptr1(new int(10));
std::shared_ptr<int> sptr2 = sptr1;
std::cout << "ptr1 use_count: " << sptr1.use_count() << std::endl;
std::cout << "ptr2 use_count: " << sptr2.use_count() << std::endl;
sptr1.reset();
std::cout << "ptr1 use_count: " << sptr1.use_count() << std::endl;
std::cout << "ptr2 use_count: " << sptr2.use_count() << std::endl;
return 0;
}
智能指针在实际开发中的应用案例
示例代码
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() {
std::cout << "MyClass Constructor" << std::endl;
}
~MyClass() {
std::cout << "MyClass Destructor" << std::endl;
}
};
int main() {
// 使用unique_ptr
{
std::unique_ptr<MyClass> uptr(new MyClass());
}
// 使用shared_ptr
{
std::shared_ptr<MyClass> sptr1(new MyClass());
std::shared_ptr<MyClass> sptr2 = sptr1;
}
return 0;
}
多个智能指针共享资源案例
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() {
std::cout << "MyClass Constructor" << std::endl;
}
~MyClass() {
std::cout << "MyClass Destructor" << std::endl;
}
};
int main() {
std::shared_ptr<MyClass> sptr1(new MyClass());
std::shared_ptr<MyClass> sptr2 = sptr1;
std::cout << "use_count: " << sptr1.use_count() << std::endl;
sptr1.reset();
std::cout << "use_count: " << sptr2.use_count() << std::endl;
return 0;
}