# 引用语义多态 vs 值语义多态

#include <iostream>
#include <vector>

class Shape {
public:
virtual void draw() const = 0;
virtual ~Shape() {}
// 注意：为实现值语义，提供一个克隆方法
virtual Shape* clone() const = 0;
};

class Circle : public Shape {
public:
void draw() const override {
std::cout << "Drawing Circle\n";
}
Circle* clone() const override {
return new Circle(*this);
}
};

class Square : public Shape {
public:
void draw() const override {
std::cout << "Drawing Square\n";
}
Square* clone() const override {
return new Square(*this);
}
};

int main() {
std::vector<Shape*> shapes;
shapes.push_back(new Circle());
shapes.push_back(new Square());

std::vector<Shape*> shapes_copy;
for (auto* shape : shapes) {
shapes_copy.push_back(shape->clone()); // 使用克隆方法
}

for (auto* shape : shapes_copy) {
shape->draw(); // 使用拷贝后的对象
}

// 清理
for (auto* shape : shapes) {
delete shape;
}
for (auto* shape : shapes_copy) {
delete shape;
}
}

#include <iostream>
#include <variant>
#include <vector>

// 定义几种不同的形状
struct Circle {
void draw() const { std::cout << "Drawing a circle.\n"; }
};

struct Square {
void draw() const { std::cout << "Drawing a square.\n"; }
};

struct Triangle {
void draw() const { std::cout << "Drawing a triangle.\n"; }
};

// 创建一个类型别名，代表可以是Circle, Square或Triangle的变体
using Shape = std::variant<Circle, Square, Triangle>;

int main() {
// 创建一个Shape的vector
std::vector<Shape> shapes;
shapes.push_back(Circle());
shapes.push_back(Square());
shapes.push_back(Triangle());

// 遍历shapes，使用visit来调用正确的draw函数
for (const auto& shape : shapes) {
std::visit([](const auto& s) { s.draw(); }, shape);
}

return 0;
}

#include <iostream>
#include <vector>
#include <memory>

class Shape {
public:
virtual void draw() const = 0;
virtual ~Shape() {}
};

class Circle : public Shape {
public:
void draw() const override {
std::cout << "Drawing Circle\n";
}
};

class Square : public Shape {
public:
void draw() const override {
std::cout << "Drawing Square\n";
}
};

int main() {
std::vector<std::shared_ptr<Shape>> shapes;
shapes.push_back(std::make_shared<Circle>());
shapes.push_back(std::make_shared<Square>());

for (const auto& shape : shapes) {
shape->draw(); // 使用原始对象
}
}