总结c++中级用法20例

1. 标准模板库 (STL)
a. vector 动态数组

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // 遍历vector
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 添加元素
    numbers.push_back(6);

    // 访问元素
    std::cout << "First element: " << numbers[0] << std::endl;

    return 0;
}

b. map 键值对

#include <iostream>
#include <map>

int main() {
    std::map<std::string, int> ageMap;
    ageMap["Alice"] = 30;
    ageMap["Bob"] = 25;

    // 遍历map
    for (const auto& pair : ageMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    // 查找元素
    if (ageMap.find("Alice") != ageMap.end()) {
        std::cout << "Alice's age: " << ageMap["Alice"] << std::endl;
    }

    return 0;
}

2. 模板
a. 函数模板

#include <iostream>

template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    std::cout << "int: " << add(3, 4) << std::endl;
    std::cout << "double: " << add(3.5, 4.5) << std::endl;

    return 0;
}

b. 类模板

#include <iostream>

template <typename T>
class Box {
public:
    Box(T value) : value(value) {}
    T getValue() { return value; }

private:
    T value;
};

int main() {
    Box<int> intBox(123);
    Box<std::string> strBox("Hello");

    std::cout << "intBox: " << intBox.getValue() << std::endl;
    std::cout << "strBox: " << strBox.getValue() << std::endl;

    return 0;
}

3. 继承和多态
a. 基本继承

#include <iostream>

class Animal {
public:
    void eat() {
        std::cout << "Animal is eating." << std::endl;
    }
};

class Dog : public Animal {
public:
    void bark() {
        std::cout << "Dog is barking." << std::endl;
    }
};

int main() {
    Dog dog;
    dog.eat();  // 继承自Animal
    dog.bark();

    return 0;
}

b. 多态

#include <iostream>

class Animal {
public:
    virtual void makeSound() {
        std::cout << "Some generic animal sound." << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Bark!" << std::endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() override {
        std::cout << "Meow!" << std::endl;
    }
};

void playSound(Animal* animal) {
    animal->makeSound();
}

int main() {
    Dog dog;
    Cat cat;

    playSound(&dog);  // 输出: Bark!
    playSound(&cat);  // 输出: Meow!

    return 0;
}

4. 异常处理

#include <iostream>

int main() {
    try {
        int divisor = 0;
        if (divisor == 0) {
            throw std::runtime_error("除数不能为零");
        }
        int result = 10 / divisor;
        std::cout << "Result: " << result << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "捕获到异常: " << e.what() << std::endl;
    }

    return 0;
}

5. 智能指针
智能指针是C++11引入的,用于自动管理内存,避免内存泄漏。
a. unique_ptr 独占所有权的智能指针,不能共享。

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "构造函数" << std::endl; }
    ~MyClass() { std::cout << "析构函数" << std::endl; }
    void display() { std::cout << "显示内容" << std::endl; }
};

int main() {
    std::unique_ptr<MyClass> ptr1(new MyClass()); // 使用unique_ptr管理MyClass对象
    ptr1->display();
    if (!ptr1) {
        std::cout << "ptr1现在为空" << std::endl;
    } else {
		std::cout << "ptr1现在不为空" << std::endl;	
	}
    // std::unique_ptr<MyClass> ptr2 = ptr1; // 不能复制unique_ptr
	std::cout << "使用move转移ptr1所有权" << std::endl;
    std::unique_ptr<MyClass> ptr2 = std::move(ptr1); // 使用move转移所有权

    if (!ptr1) {
        std::cout << "ptr1现在为空" << std::endl;
    }
    ptr2->display();

    return 0;
}

b. shared_ptr 共享所有权的智能指针,多个指针可以共同拥有资源。

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "构造函数" << std::endl; }
    ~MyClass() { std::cout << "析构函数" << std::endl; }
    void display() { std::cout << "显示内容" << std::endl; }
};

int main() {
    std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
    {
        std::shared_ptr<MyClass> ptr2 = ptr1; // 共享所有权
        ptr2->display();
        std::cout << "ptr2 离开作用域" << std::endl;
    }
    std::cout << "ptr1仍然有效" << std::endl;
    ptr1->display();

    return 0;
}

c.weak_ptr用于解决循环引用问题,它不改变资源的引用计数。

#include <iostream>
#include <memory>

class Resource {
public:
    std::weak_ptr<Resource> other;
    Resource() { std::cout << "资源已分配" << std::endl; }
    ~Resource() { std::cout << "资源已释放" << std::endl; }
    void print() { std::cout << "使用资源" << std::endl; }
};

int main() {
    {
        std::shared_ptr<Resource> res1 = std::make_shared<Resource>();
        std::shared_ptr<Resource> res2 = std::make_shared<Resource>();

        res1->other = res2;
        res2->other = res1;

        std::cout << "引用计数: " << res1.use_count() << std::endl;  // 输出: 1
        std::cout << "引用计数: " << res2.use_count() << std::endl;  // 输出: 1
    }  // 资源自动释放

    return 0;
}

6. Lambda表达式
Lambda表达式是C++11引入的一种用于定义匿名函数的简洁方法。

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // 使用Lambda表达式打印元素
    std::for_each(numbers.begin(), numbers.end(), [](int num) {
        std::cout << num << " ";
    });
    std::cout << std::endl;

    // 使用Lambda表达式计算平方
    std::for_each(numbers.begin(), numbers.end(), [](int& num) {
        num = num * num;
    });

    // 打印平方后的结果
    std::for_each(numbers.begin(), numbers.end(), [](int num) {
        std::cout << num << " ";
    });
    std::cout << std::endl;

    return 0;
}

7. 文件操作
C++通过库进行文件操作。

#include <iostream>
#include <fstream>
#include <string>

int main() {
    // 写入文件
    std::ofstream outFile("example.txt");
    if (outFile.is_open()) {
        outFile << "这是一个例子文件。\n";
        outFile << "包含多行文本。\n";
        outFile.close();
    } else {
        std::cerr << "无法打开文件进行写入。" << std::endl;
    }

    // 读取文件
    std::ifstream inFile("example.txt");
    if (inFile.is_open()) {
        std::string line;
        while (getline(inFile, line)) {
            std::cout << line << std::endl;
        }
        inFile.close();
    } else {
        std::cerr << "无法打开文件进行读取。" << std::endl;
    }

    return 0;
}

8. 多线程编程
C++11引入了多线程支持,可以使用库进行多线程编程。

#include <iostream>
#include <thread>

void printMessage(const std::string& message) {
    std::cout << message << std::endl;
}

int main() {
    std::thread t1(printMessage, "Hello from thread 1");
    std::thread t2(printMessage, "Hello from thread 2");

    // 等待线程完成
    t1.join();
    t2.join();

    return 0;
}

9. C++11/14/17/20新特性
C++许多新特性,例如auto、nullptr、range-based for、constexpr、structured bindings等。
a. auto关键字

#include <iostream>
#include <vector>

int main() {
    auto x = 5; // 编译器推断x为int
    auto y = 3.14; // 编译器推断y为double

    std::vector<int> numbers = {1, 2, 3, 4, 5};
    for (auto num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

b. nullptr关键字

#include <iostream>

void foo(int* ptr) {
    if (ptr) {
        std::cout << "指针非空" << std::endl;
    } else {
        std::cout << "指针为空" << std::endl;
    }
}

int main() {
    int* p = nullptr; // 使用nullptr初始化指针
    foo(p);

    return 0;
}

c. range-based for循环

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

d. constexpr关键字

#include <iostream>

constexpr int square(int x) {
    return x * x;
}

int main() {
    constexpr int result = square(5); // 编译时计算
    std::cout << "Square of 5 is: " << result << std::endl;

    return 0;
}

10. 命名空间
命名空间用于避免命名冲突

#include <iostream>

namespace first {
    void display() {
        std::cout << "第一命名空间" << std::endl;
    }
}

namespace second {
    void display() {
        std::cout << "第二命名空间" << std::endl;
    }
}

int main() {
    first::display();
    second::display();

    return 0;
}

11. 运算符重载
运算符重载允许你为自定义类型定义新的运算行为。

#include <iostream>

class Complex {
public:
    Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}

    // 重载加法运算符
    Complex operator + (const Complex& other) {
        return Complex(real + other.real, imag + other.imag);
    }

    void display() {
        std::cout << real << " + " << imag << "i" << std::endl;
    }

private:
    double real, imag;
};

int main() {
    Complex c1(3.0, 4.0);
    Complex c2(1.0, 2.0);
    Complex c3 = c1 + c2;

    c3.display();

    return 0;
}

12. 标准库算法

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> numbers = {5, 3, 1, 4, 2};

    // 排序
    std::sort(numbers.begin(), numbers.end());
    std::cout << "排序后: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 查找
    auto it = std::find(numbers.begin(), numbers.end(), 3);
    if (it != numbers.end()) {
        std::cout << "找到数字 3" << std::endl;
    } else {
        std::cout << "未找到数字 3" << std::endl;
    }

    return 0;
}

13. 类型转换

#include <iostream>

int main() {
    // static_cast
    int a = 10;
    double b = static_cast<double>(a);
    std::cout << "static_cast: " << b << std::endl;

    // const_cast
    const int c = 20;
    int* d = const_cast<int*>(&c);
    *d = 30;
    std::cout << "const_cast: " << c << std::endl;  // 注意:修改const变量的行为是未定义的

    return 0;
}

14. 动态内存管理
C++使用new和delete进行动态内存管理。

#include <iostream>

int main() {
    // 动态分配一个整数
    int* p = new int(10);
    std::cout << "动态分配的整数: " << *p << std::endl;
    delete p;  // 释放内存

    // 动态分配一个数组
    int* arr = new int[5] {1, 2, 3, 4, 5};
    std::cout << "动态分配的数组: ";
    for (int i = 0; i < 5; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;
    delete[] arr;  // 释放数组内存

    return 0;
}

15. 函数对象
函数对象是一个重载了operator()的对象,可以像函数一样调用。

#include <iostream>
#include <vector>
#include <algorithm>

class Add {
public:
    int operator()(int a, int b) {
        return a + b;
    }
};

int main() {
    Add add;
    int result = add(3, 4);
    std::cout << "函数对象调用结果: " << result << std::endl;

    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::for_each(numbers.begin(), numbers.end(), [](int &num) { num = num * 2; });
    std::cout << "使用Lambda修改后的数组: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

16. 标准库容器
a. list 链表

#include <iostream>
#include <list>

int main() {
    std::list<int> numbers = {1, 2, 3, 4, 5};

    numbers.push_back(6);
    numbers.push_front(0);

    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

b. set 集合

#include <iostream>
#include <set>

int main() {
    std::set<int> numbers = {1, 2, 3, 4, 5};

    numbers.insert(6);
    numbers.insert(3);  // 重复插入无效

    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

17. 友元函数和友元类
友元函数和友元类允许你访问类的私有成员。
a.友元函数

#include <iostream>

class Box {
private:
    double width;

public:
    Box(double w) : width(w) {}

    friend void printWidth(Box box);  // 友元函数声明
};

void printWidth(Box box) {
    std::cout << "Box 宽度: " << box.width << std::endl;  // 访问私有成员
}

int main() {
    Box box(10.0);
    printWidth(box);

    return 0;
}

b.友元类

#include <iostream>

class ClassB;  // 前向声明

class ClassA {
public:
    void show(ClassB& b);
};

class ClassB {
private:
    int b;

public:
    ClassB(int val) : b(val) {}

    friend class ClassA;  // 声明 ClassA 为友元类
};

void ClassA::show(ClassB& b) {
    std::cout << "ClassB 的私有成员 b: " << b.b << std::endl;
}

int main() {
    ClassB objB(10);
    ClassA objA;
    objA.show(objB);

    return 0;
}

18. 移动语义
C++11引入了移动语义,通过std::move和移动构造函数、移动赋值运算符实现高效的资源管理。

#include <iostream>
#include <utility>

class MyClass {
public:
    int* data;

    // 构造函数
    MyClass(int value) : data(new int(value)) {
        std::cout << "构造函数: 分配资源" << std::endl;
    }

    // 移动构造函数
    MyClass(MyClass&& other) noexcept : data(other.data) {
        other.data = nullptr;
        std::cout << "移动构造函数: 转移资源" << std::endl;
    }

    // 移动赋值运算符
    MyClass& operator=(MyClass&& other) noexcept {
        if (this != &other) {
            delete data;           // 释放当前资源
            data = other.data;     // 转移资源
            other.data = nullptr;
            std::cout << "移动赋值运算符: 转移资源" << std::endl;
        }
        return *this;
    }

    // 析构函数
    ~MyClass() {
        delete data;
        std::cout << "析构函数: 释放资源" << std::endl;
    }
};

int main() {
    MyClass obj1(10);
    MyClass obj2 = std::move(obj1);  // 调用移动构造函数

    return 0;
}

19.混合编程(C++与其他语言结合)
C++可以与其他编程语言结合使用,通常是通过外部库或语言绑定。

#include <iostream>

extern "C" {
    #include <math.h>  // 使用C语言的math库
}

int main() {
    double result = sqrt(16.0);  // 调用C库函数
    std::cout << "sqrt(16.0) = " << result << std::endl;

    return 0;
}

20.工厂模式
工厂模式用于创建对象的接口,使得子类可以决定实例化哪一个类。

#include <iostream>
#include <memory>

// 产品接口
class Product {
public:
    virtual ~Product() = default;
    virtual void use() = 0;
};

// 具体产品A
class ConcreteProductA : public Product {
public:
    void use() override {
        std::cout << "使用产品A" << std::endl;
    }
};

// 具体产品B
class ConcreteProductB : public Product {
public:
    void use() override {
        std::cout << "使用产品B" << std::endl;
    }
};

// 工厂接口
class Factory {
public:
    virtual ~Factory() = default;
    virtual std::unique_ptr<Product> createProduct() = 0;
};

// 具体工厂A
class ConcreteFactoryA : public Factory {
public:
    std::unique_ptr<Product> createProduct() override {
        return std::make_unique<ConcreteProductA>();
    }
};

// 具体工厂B
class ConcreteFactoryB : public Factory {
public:
    std::unique_ptr<Product> createProduct() override {
        return std::make_unique<ConcreteProductB>();
    }
};

int main() {
    std::unique_ptr<Factory> factoryA = std::make_unique<ConcreteFactoryA>();
    std::unique_ptr<Factory> factoryB = std::make_unique<ConcreteFactoryB>();

    std::unique_ptr<Product> productA = factoryA->createProduct();
    std::unique_ptr<Product> productB = factoryB->createProduct();

    productA->use();  // 输出: 使用产品A
    productB->use();  // 输出: 使用产品B

    return 0;
}

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值