C++学习之旅:复习

前言

大家好啊!今天咱们来聊聊C++这门既强大又"倔强"的语言。有人说C++是把双刃剑,用得好能削铁如泥,用不好可能把自己削了。哈哈,确实如此!但只要掌握了正确的学习路线,这把"剑"绝对能成为你职业生涯中的一大利器。

一、基础入门知识

C++的入门就像学做菜,先得认识各种食材和基本工具,才能烹饪出美味佳肴。

1. 数据类型与变量

C++的基本数据类型包括整型(int)、浮点型(float, double)、字符型(char)和布尔型(bool)。想象一下,这些类型就像不同的容器,有的适合装整数,有的适合装小数。

int age = 28;         // 整型,就像一个只能装整数的盒子

double salary = 10000.5;  // 双精度浮点型,可以装带小数点的数字

char grade = 'A';     // 字符型,只能装单个字符

bool isPassed = true; // 布尔型,只能是true或false

2. 运算符与表达式

运算符就像厨房里的各种刀具,不同的刀具有不同的用途。

int a = 10, b = 3;

int sum = a + b;      // 加法,结果为13

int diff = a - b;     // 减法,结果为7

int product = a * b;  // 乘法,结果为30

int quotient = a / b; // 整数除法,结果为3(注意:不是3.33)

int remainder = a % b; // 取余,结果为1

3. 控制流

控制流就像是你烹饪时的决策过程,根据不同条件采取不同行动。

条件语句
if (score >= 90) {

    cout << "优秀!";

} else if (score >= 60) {

    cout << "及格";

} else {

    cout << "不及格,加油!";

}
循环语句
// for循环,就像是按部就班地完成一系列任务

for (int i = 0; i < 5; i++) {

    cout << i << " ";  // 输出:0 1 2 3 4

}

// while循环,就像是"只要条件满足,就一直做"

int j = 0;

while (j < 5) {

    cout << j << " ";  // 输出:0 1 2 3 4

    j++;

}

二、类和对象

面向对象编程是C++的精髓所在,这就像从简单的小饭馆升级到了星级酒店的厨房管理。

1. 类的定义与对象创建

类就像是一个蓝图,定义了对象应该具有的属性(数据成员)和行为(成员函数)。

class Car {

private:

    string brand;

    int speed;

    

public:

    // 构造函数

    Car(string b) : brand(b), speed(0) {}

    

    // 成员函数

    void accelerate() {

        speed += 10;

        cout << brand << "加速了,当前速度:" << speed << "km/h" << endl;

    }

    

    void brake() {

        if (speed >= 10) speed -= 10;

        else speed = 0;

        cout << brand << "刹车了,当前速度:" << speed << "km/h" << endl;

    }

};

// 创建对象

Car myCar("奔驰");

myCar.accelerate(); // 输出:奔驰加速了,当前速度:10km/h

myCar.brake();      // 输出:奔驰刹车了,当前速度:0km/h

2. 继承与多态

继承就像是"青出于蓝而胜于蓝",子类继承父类的特性并可以扩展新功能。

class ElectricCar : public Car {

private:

    int batteryLevel;

    

public:

    ElectricCar(string b) : Car(b), batteryLevel(100) {}

    

    void chargeBattery() {

        batteryLevel = 100;

        cout << "电池已充满!" << endl;

    }

    

    // 重写父类方法,这就是多态

    void accelerate() override {

        Car::accelerate(); // 调用父类方法

        batteryLevel -= 5;

        cout << "电池剩余:" << batteryLevel << "%" << endl;

    }

};

多态就像餐厅里的"今日特色",虽然都是一道菜,但不同厨师有不同做法。

三、模板

模板是C++中的"一次编写,多种类型"的神器,就像是可以根据原料自动调整的食谱。

// 函数模板

template <typename T>

T max(T a, T b) {

    return (a > b) ? a : b;

}

int maxInt = max(10, 20);         // 返回20

double maxDouble = max(3.14, 2.71); // 返回3.14

// 类模板

template <typename T>

class Container {

private:

    T data;

    

public:

    Container(T value) : data(value) {}

    

    T getValue() {

        return data;

    }

};

Container<int> intContainer(42);

Container<string> strContainer("Hello");

模板就像是一种"代码复用"的艺术,让你的代码既简洁又灵活。

四、继承和多态

C++的继承和多态机制就像生物界的进化,子类在父类的基础上不断发展壮大。

继承的类型

  • 公有继承(public): 最常用,子类可以访问父类的public和protected成员
  • 保护继承(protected): 父类的public成员在子类中变为protected
  • 私有继承(private): 父类的public和protected成员在子类中都变为private

多态的实现

多态通过虚函数来实现,就像是同一个指令,不同对象有不同的反应。

class Animal {

public:

    virtual void makeSound() {

        cout << "动物发出声音" << endl;

    }

};

class Dog : public Animal {

public:

    void makeSound() override {

        cout << "汪汪汪!" << endl;

    }

};

class Cat : public Animal {

public:

    void makeSound() override {

        cout << "喵喵喵~" << endl;

    }

};

// 多态的魅力

Animal* pet1 = new Dog();

Animal* pet2 = new Cat();

pet1->makeSound(); // 输出:汪汪汪!

pet2->makeSound(); // 输出:喵喵喵~

五、智能指针

智能指针是C++11引入的内存管理利器,就像有了自动清洁的厨房,再也不用担心"垃圾"没处理了。

// 独占所有权的智能指针

unique_ptr<int> p1(new int(42));

// p1会在离开作用域时自动释放内存

// 不能复制unique_ptr

// unique_ptr<int> p2 = p1; // 编译错误!

// 可以移动所有权

unique_ptr<int> p3 = move(p1); // p1现在为空,p3接管了资源

// 共享所有权的智能指针

shared_ptr<int> sp1(new int(100));

{

    shared_ptr<int> sp2 = sp1; // 引用计数增加到2

    cout << *sp2 << endl;      // 输出:100

} // sp2离开作用域,引用计数减为1

// weak_ptr不会增加引用计数,可以避免循环引用问题

weak_ptr<int> wp = sp1;

智能指针的使用让内存管理变得简单而安全,大大减少了内存泄漏的风险。

六、C++11新特性

C++11像是给语言注入了新的活力,添加了许多现代特性。

1. auto关键字

auto让编译器自动推导变量类型,写代码更加简洁。

auto i = 42;        // int

auto d = 3.14;      // double

auto s = "hello";   // const char*

auto v = vector<int>{1, 2, 3}; // vector<int>

2. 范围for循环

遍历容器元素变得更加简单直观。

vector<int> nums = {1, 2, 3, 4, 5};

// 传统方式

for (size_t i = 0; i < nums.size(); i++) {

    cout << nums[i] << " ";

}

// 范围for循环

for (const auto& num : nums) {

    cout << num << " ";

}

3. Lambda表达式

函数式编程的精髓,小巧而强大。

auto sum = [](int a, int b) -> int { return a + b; };

cout << sum(3, 4) << endl; // 输出:7

vector<int> numbers = {1, 3, 5, 2, 4};

sort(numbers.begin(), numbers.end(), [](int a, int b) {

    return a > b; // 降序排列

});

// numbers现在是{5, 4, 3, 2, 1}

七、异常处理

异常处理就像是烹饪过程中的"意外情况处理方案",让程序在遇到问题时能够优雅地处理。

try {

    int* arr = new int[1000000000]; // 尝试分配大量内存

} catch (const bad_alloc& e) {

    cout << "内存分配失败:" << e.what() << endl;

}

// 自定义异常

class DivideByZeroException : public exception {

public:

    const char* what() const noexcept override {

        return "除数不能为零!";

    }

};

double divide(double a, double b) {

    if (b == 0) {

        throw DivideByZeroException();

    }

    return a / b;

}

try {

    cout << divide(10, 0) << endl;

} catch (const DivideByZeroException& e) {

    cout << "错误:" << e.what() << endl;

}

八、四种强制类型转换

C++提供了四种不同用途的类型转换操作符,比C语言的强制类型转换更加安全和明确。

// 1. static_cast:基本数据类型转换和向上转型

double d = 3.14;

int i = static_cast<int>(d); // 浮点数转整数

// 2. dynamic_cast:安全的向下转型,运行时检查

Base* basePtr = new Derived();

Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);

if (derivedPtr) {

    // 转换成功

}

// 3. const_cast:去除const属性

const int c = 10;

int* p = const_cast<int*>(&c);

// 4. reinterpret_cast:进行低级转换,如指针到整数

int* ptr = new int(42);

uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);

九、设计模式

设计模式是解决特定问题的经验总结,就像是厨师的"独门秘籍"。

1. 单例模式

确保一个类只有一个实例,并提供全局访问点。

class Singleton {

private:

    static Singleton* instance;

    Singleton() {} // 私有构造函数

    

public:

    static Singleton* getInstance() {

        if (instance == nullptr) {

            instance = new Singleton();

        }

        return instance;

    }

};

Singleton* Singleton::instance = nullptr;

2. 工厂模式

将对象的创建与使用分离,增加灵活性。

class Product {

public:

    virtual void use() = 0;

    virtual ~Product() {}

};

class ConcreteProductA : public Product {

public:

    void use() override {

        cout << "使用产品A" << endl;

    }

};

class ConcreteProductB : public Product {

public:

    void use() override {

        cout << "使用产品B" << endl;

    }

};

class Factory {

public:

    static Product* createProduct(char type) {

        if (type == 'A') return new ConcreteProductA();

        else if (type == 'B') return new ConcreteProductB();

        return nullptr;

    }

};

十、STL(标准模板库)

STL是C++的一大杀器,就像是厨房里的各种高级厨具,极大提高了编程效率。

1. 容器

STL提供了各种容器,满足不同的数据存储需求。

// 动态数组

vector<int> vec = {1, 2, 3};

vec.push_back(4); // 添加元素

// 双端队列

deque<int> dq = {1, 2, 3};

dq.push_front(0); // 在前端添加元素

// 关联容器

map<string, int> scores;

scores["Alice"] = 95;

scores["Bob"] = 89;

// 查找元素

auto it = scores.find("Alice");

if (it != scores.end()) {

    cout << it->first << ": " << it->second << endl;

}

2. 算法

STL算法让复杂操作变得简单高效。

vector<int> nums = {3, 1, 4, 1, 5, 9};

// 排序

sort(nums.begin(), nums.end());

// 查找

auto it = find(nums.begin(), nums.end(), 4);

if (it != nums.end()) {

    cout << "找到了:" << *it << endl;

}

// 转换

vector<int> squared;

transform(nums.begin(), nums.end(), back_inserter(squared),

          [](int x) { return x * x; });

总结

C++是一门深不可测的语言,学习曲线可能有点陡,但掌握了它就像拥有了一把瑞士军刀,几乎可以解决任何编程问题。希望这篇博客能帮助你梳理C++的关键知识点,在复习的道路上更加轻松愉快!

记住,学习编程最重要的是动手实践。看再多的教程,不如亲自写几行代码来得实在。所以,打开你的IDE,开始编码吧!有什么问题随时找我讨论,一起在C++的海洋里遨游!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值