gpt4 book ai didi

c++ - boost 变体 : Get pointer of generic class providing a variant

转载 作者:太空狗 更新时间:2023-10-29 23:15:37 25 4
gpt4 key购买 nike

我有一个 boost::variant 定义如下:

typedef boost::variant<Rectangle, Circle> Shape;

现在我想从 Rectangle 中获取一个 Shape 指针:

Rectangle *rectanglePointer = new Rectangle();
Shape *shapePointer = rectanglePointer;

但它不起作用。我在这里弄错了什么?

最佳答案

简单。变体不是那样工作的。

它们专门用于静态多态性。

您/可以/存储运行时多态引用(或指针),但您仍然需要使用 boost::get<>或访问者提取实际值(value)。

在你的例子中,Shape显然不是 Rectangle 的基类,这就是编译器将拒绝静态转换的原因(向上转换不适用于不相关的类型 RectangleShape)。

变体,简单

一个带有变体的简单例子:

Live On Coliru

#include <boost/variant.hpp>
#include <iostream>

struct Circle {
friend std::ostream& operator<<(std::ostream& os, Circle) {
return os << "Circle";
}
};

struct Rectangle {
friend std::ostream& operator<<(std::ostream& os, Rectangle) {
return os << "Rectangle";
}
};

using Shape = boost::variant<Circle, Rectangle>;


int main() {

Shape shape = Rectangle();
std::cout << shape << "\n";

shape = Circle();
std::cout << shape << "\n";

}

变体:area(Shape)实现

Live On Coliru

#include <boost/variant.hpp>
#include <iostream>

struct Point { double x,y; };

struct Circle {

Point centre;
double radius;

friend std::ostream& operator<<(std::ostream& os, Circle) {
return os << "Circle";
}
};

struct Rectangle {
Point topleft, bottomright;

friend std::ostream& operator<<(std::ostream& os, Rectangle) {
return os << "Rectangle";
}
};

struct area_f : boost::static_visitor<double> {
double operator()(Rectangle const& r) const {
return std::abs(r.bottomright.x - r.topleft.x) *
std::abs(r.bottomright.y - r.topleft.y);
}
double operator()(Circle const& r) const {
return (r.radius*r.radius) * M_PI;
}
};

using Shape = boost::variant<Circle, Rectangle>;

double area(Shape const& s) {
return boost::apply_visitor(area_f(), s);
}

int main() {

Shape shape = Rectangle { { 1,1 }, { 5,5 } };
std::cout << shape << ": " << area(shape) << "\n";

shape = Circle { { 10, 10 }, 5 };
std::cout << shape << ": " << area(shape) << "\n";

}

动态多态

同样使用你可以在其他语言中使用的多态性:

Live On Coliru

#include <iostream>
#include <cmath>

struct Point { double x,y; };

struct Shape {
virtual ~Shape() {}
virtual double area() const = 0;
protected:
virtual void print(std::ostream& os) const = 0;

friend std::ostream& operator<<(std::ostream& os, Shape const& s) {
s.print(os);
return os;
}
};

struct Circle : Shape {
Circle(Point c, double r) : centre(c), radius(r) {}

Point centre;
double radius;

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

virtual ~Circle() { }

protected:
virtual void print(std::ostream& os) const override {
os << "Circle";
}
};

struct Rectangle : Shape {
Rectangle(Point tl, Point br) : topleft(tl), bottomright(br) {}

Point topleft, bottomright;

virtual double area() const override {
return std::abs(bottomright.x - topleft.x) *
std::abs(bottomright.y - topleft.y);
}

virtual ~Rectangle() { }
protected:
virtual void print(std::ostream& os) const override {
os << "Rectangle";
}

};

int main() {
Rectangle r { { 1,1 }, { 5,5 } };

{
Shape const& shape = r;
std::cout << shape << ": " << shape.area() << "\n";
}

Circle c { { 10, 10 }, 5 };
{
Shape const& shape = c;
std::cout << shape << ": " << shape.area() << "\n";
}

}

关于c++ - boost 变体 : Get pointer of generic class providing a variant,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28349732/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com