编译运行: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;
}