手记

C++高级语法入门教程

概述

本文深入探讨了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;
}
0人推荐
随时随地看视频
慕课网APP