瀏覽代碼

start_example

Marcelo Fornet 5 年之前
當前提交
022482b077
共有 10 個文件被更改,包括 134 次插入0 次删除
  1. 7 0
      .vscode/settings.json
  2. 5 0
      circle.h
  3. 9 0
      circle_shape.cpp
  4. 4 0
      circle_shape.h
  5. 22 0
      main.cpp
  6. 5 0
      rectangle.h
  7. 9 0
      rectangle_shape.cpp
  8. 6 0
      rectangle_shape.h
  9. 12 0
      shape.h
  10. 55 0
      trait.h

+ 7 - 0
.vscode/settings.json

@@ -0,0 +1,7 @@
+{
+    "files.associations": {
+        "functional": "cpp",
+        "__split_buffer": "cpp",
+        "vector": "cpp"
+    }
+}

+ 5 - 0
circle.h

@@ -0,0 +1,5 @@
+// circle.h
+struct Circle
+{
+    const double radius = 4.0;
+};

+ 9 - 0
circle_shape.cpp

@@ -0,0 +1,9 @@
+// circle_shape.cpp
+namespace ShapeImpl
+{
+double area(const Circle &circle)
+{
+    double r = circle.radius;
+    return 3.14 * r * r;
+}
+} // namespace ShapeImpl

+ 4 - 0
circle_shape.h

@@ -0,0 +1,4 @@
+namespace ShapeImpl
+{
+double area(const Circle &circle);
+}

+ 22 - 0
main.cpp

@@ -0,0 +1,22 @@
+#include "trait.h"
+#include "circle.h"
+#include "rectangle.h"
+#include "circle_shape.h"
+#include "rectangle_shape.h"
+#include "shape.h"
+#include <vector>
+
+using namespace std;
+
+int main()
+{
+    vector<Shape> geometries;
+    geometries.emplace_back(Circle());
+    // geometries.emplace_back(Rectangle());
+
+    for (const auto &shape : geometries)
+    {
+        cout << shape.area() << endl;
+    }
+    return 0;
+}

+ 5 - 0
rectangle.h

@@ -0,0 +1,5 @@
+struct Rectangle
+{
+    const double width = 2.0;
+    const double height = 3.0;
+};

+ 9 - 0
rectangle_shape.cpp

@@ -0,0 +1,9 @@
+
+// rectangle_shape.cpp
+namespace ShapeImpl
+{
+double area(const Rectangle &rectangle)
+{
+    return rectangle.width * rectangle.height;
+}
+} // namespace ShapeImpl

+ 6 - 0
rectangle_shape.h

@@ -0,0 +1,6 @@
+
+// rectangle_shape.h
+namespace ShapeImpl
+{
+double area(const Rectangle &rectangle);
+}

+ 12 - 0
shape.h

@@ -0,0 +1,12 @@
+#include "trait.h"
+
+struct Shape : public Trait
+{
+    template <typename T>
+    Shape(T t)
+        : Trait(std::move(t)), area([this]() { return ShapeImpl::area(cast<T>()); })
+    {
+    }
+
+    std::function<double()> area;
+};

+ 55 - 0
trait.h

@@ -0,0 +1,55 @@
+#ifndef AAB
+#define AAB
+#include <functional>
+#include <iostream>
+#include <memory>
+
+using namespace std;
+
+struct Trait
+{
+public:
+    Trait(const Trait &trait) = default;
+    Trait(Trait &&trait) = default;
+    Trait &operator=(const Trait &trait) = default;
+    Trait &operator=(Trait &&trait) = default;
+    virtual ~Trait() = default;
+
+    template <typename T>
+    explicit Trait(T t)
+        : container(std::make_shared<Model<T>>(std::move(t)))
+    {
+    }
+
+    template <typename T>
+    T cast()
+    {
+        auto typed_container = std::static_pointer_cast<const Model<T>>(container);
+        return typed_container->m_data;
+    }
+
+private:
+    struct Concept
+    {
+        // All need to be explicitly defined just to make the destructor virtual
+        Concept() = default;
+        Concept(const Concept &concept) = default;
+        Concept(Concept &&concept) = default;
+        Concept &operator=(const Concept &concept) = default;
+        Concept &operator=(Concept &&concept) = default;
+        virtual ~Concept() = default;
+    };
+
+    template <typename T>
+    struct Model : public Concept
+    {
+        Model(T x)
+            : m_data(move(x))
+        {
+        }
+        T m_data;
+    };
+
+    std::shared_ptr<const Concept> container;
+};
+#endif