Skip to content

Instantly share code, notes, and snippets.

@terasakisatoshi
Created December 20, 2024 22:09
Show Gist options
  • Select an option

  • Save terasakisatoshi/094e019081255b8979f707e15d42b40b to your computer and use it in GitHub Desktop.

Select an option

Save terasakisatoshi/094e019081255b8979f707e15d42b40b to your computer and use it in GitHub Desktop.
Shared ptr と C++, 継承
#include <iostream>
#include <memory>
#include <vector>
#include <cmath>
// 基底クラス: Shape
class Shape : public std::enable_shared_from_this<Shape> {
public:
virtual double area() const = 0; // 純粋仮想関数: 面積を計算
virtual void draw() const = 0; // 純粋仮想関数: 描画
virtual ~Shape() = default; // 仮想デストラクタ
// 自身の shared_ptr を取得するメソッド
std::shared_ptr<Shape> getPtr() {
return shared_from_this();
}
};
// 派生クラス: Circle
class Circle : public Shape {
private:
double radius; // 半径
public:
explicit Circle(double r) : radius(r) {}
double area() const override {
return M_PI * radius * radius;
}
void draw() const override {
std::cout << "Drawing a circle with radius " << radius << std::endl;
}
};
// 派生クラス: Rectangle
class Rectangle : public Shape {
private:
double width; // 幅
double height; // 高さ
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() const override {
return width * height;
}
void draw() const override {
std::cout << "Drawing a rectangle with width " << width
<< " and height " << height << std::endl;
}
};
int main() {
// std::shared_ptr で図形のインスタンスを作成
auto circle = std::make_shared<Circle>(5.0);
auto rectangle = std::make_shared<Rectangle>(4.0, 6.0);
// 基底クラスのポインタで管理
std::vector<std::shared_ptr<Shape>> shapes;
shapes.push_back(circle);
shapes.push_back(rectangle);
// すべての図形を描画し、面積を表示
for (const auto& shape : shapes) {
shape->draw();
std::cout << "Area: " << shape->area() << std::endl;
}
// クラス内から自身の shared_ptr を取得
auto circlePtr = circle->getPtr();
auto rectanglePtr = rectangle->getPtr();
// 取得した shared_ptr の確認
if (circlePtr) {
std::cout << "Circle shared_ptr is valid." << std::endl;
}
if (rectanglePtr) {
std::cout << "Rectangle shared_ptr is valid." << std::endl;
}
return 0;
}
@terasakisatoshi
Copy link
Copy Markdown
Author

auto キーワードの回避版

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

// 基底クラス: Shape
class Shape : public std::enable_shared_from_this<Shape> {
public:
    virtual double area() const = 0; // 純粋仮想関数: 面積を計算
    virtual void draw() const = 0;   // 純粋仮想関数: 描画
    virtual ~Shape() = default;      // 仮想デストラクタ

    // 自身の shared_ptr を取得するメソッド
    std::shared_ptr<Shape> getPtr() {
        return shared_from_this();
    }
};

// 派生クラス: Circle
class Circle : public Shape {
private:
    double radius; // 半径

public:
    explicit Circle(double r) : radius(r) {}

    double area() const override {
        return M_PI * radius * radius;
    }

    void draw() const override {
        std::cout << "Drawing a circle with radius " << radius << std::endl;
    }
};

// 派生クラス: Rectangle
class Rectangle : public Shape {
private:
    double width;  //
    double height; // 高さ

public:
    Rectangle(double w, double h) : width(w), height(h) {}

    double area() const override {
        return width * height;
    }

    void draw() const override {
        std::cout << "Drawing a rectangle with width " << width
                  << " and height " << height << std::endl;
    }
};

int main() {
    // std::shared_ptr で図形のインスタンスを作成
    std::shared_ptr<Circle> circle(new Circle(5.0));
    std::shared_ptr<Rectangle> rectangle(new Rectangle(4.0, 6.0));

    // 基底クラスのポインタで管理
    std::vector<std::shared_ptr<Shape>> shapes;
    shapes.push_back(circle);
    shapes.push_back(rectangle);

    // すべての図形を描画し、面積を表示
    for (std::vector<std::shared_ptr<Shape>>::const_iterator it = shapes.begin(); it != shapes.end(); ++it) {
        (*it)->draw();
        std::cout << "Area: " << (*it)->area() << std::endl;
    }

    // クラス内から自身の shared_ptr を取得
    std::shared_ptr<Shape> circlePtr = circle->getPtr();
    std::shared_ptr<Shape> rectanglePtr = rectangle->getPtr();

    // 取得した shared_ptr の確認
    if (circlePtr) {
        std::cout << "Circle shared_ptr is valid." << std::endl;
    }
    if (rectanglePtr) {
        std::cout << "Rectangle shared_ptr is valid." << std::endl;
    }

    return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment