测试_第09章_面向对象.cpp

← 测试总览 · 目录

编译运行:clang++ -std=c++26 -Wall -Wextra -pthread 测试_第09章_面向对象.cpp -o t && ./t(需先 cd 测试/

// 第9章测试:面向对象
#include <print>
#include <string>
#include <vector>
#include <memory>

int failures = 0;
#define CHECK(expr)                                                         \
    do {                                                                    \
        if (!(expr)) {                                                      \
            ++failures;                                                     \
            std::println("FAIL 第{}行: {}", __LINE__, #expr);              \
        }                                                                   \
    } while (0)

// 9.1/9.2 封装 + 构造
class BankAccount {
public:
    explicit BankAccount(double balance) : balance_(balance) {}
    void deposit(double amount) { balance_ += amount; }
    bool withdraw(double amount) {
        if (amount > balance_) return false;            // 余额不足
        balance_ -= amount;
        return true;
    }
    double balance() const { return balance_; }         // 只读访问器
private:
    double balance_ = 0.0;
};

// 9.5 继承 + 多态
class Animal {
public:
    virtual std::string speak() const { return "动物叫"; }
    virtual ~Animal() = default;                        // 虚析构,必须
};
class Cat : public Animal {
public:
    std::string speak() const override { return "喵"; }
};
class Dog : public Animal {
public:
    std::string speak() const override { return "汪"; }
};

// 9.6 纯虚函数 / 抽象类
class Shape {
public:
    virtual double area() const = 0;
    virtual ~Shape() = default;
};
class Circle : public Shape {
public:
    explicit Circle(double r) : r_(r) {}
    double area() const override { return 3.14159 * r_ * r_; }
private:
    double r_;
};
class Rect : public Shape {
public:
    Rect(double w, double h) : w_(w), h_(h) {}
    double area() const override { return w_ * h_; }
private:
    double w_, h_;
};

// 9.4 移动语义演示
struct Movable {
    std::string data;
    explicit Movable(std::string d) : data(std::move(d)) {}
};

int main() {
    // 9.1 封装
    BankAccount acc(100);
    acc.deposit(50);
    CHECK(acc.balance() == 150);
    CHECK(acc.withdraw(200) == false);                  // 余额不足
    CHECK(acc.withdraw(30) == true);
    CHECK(acc.balance() == 120);

    // 9.2 构造
    std::vector<BankAccount> accounts;
    accounts.push_back(BankAccount(10.0));
    CHECK(accounts[0].balance() == 10.0);

    // 9.5 多态
    std::vector<std::unique_ptr<Animal>> zoo;
    zoo.push_back(std::make_unique<Cat>());
    zoo.push_back(std::make_unique<Dog>());
    std::string sounds;
    for (const auto& a : zoo) sounds += a->speak();
    CHECK(sounds == "喵汪");                             // 同一接口不同行为

    // 基类指针调子类
    std::unique_ptr<Animal> cat = std::make_unique<Cat>();
    CHECK(cat->speak() == "喵");

    // 9.6 抽象类
    std::vector<std::unique_ptr<Shape>> shapes;
    shapes.push_back(std::make_unique<Circle>(2.0));
    shapes.push_back(std::make_unique<Rect>(3.0, 4.0));
    double total = 0;
    for (const auto& s : shapes) total += s->area();
    CHECK(total > 24.5 && total < 24.6);                // 12.566+12

    // 9.4 移动
    std::string big = std::string(1000, 'a');
    Movable m(std::move(big));                          // 资源搬家
    CHECK(m.data.size() == 1000);

    // 9.9 struct 默认 public
    struct Config { int w = 800; int h = 600; };
    Config cfg;
    CHECK(cfg.w == 800);

    if (failures == 0) std::println("全部通过");
    return failures;
}