我有一些C结构,我想延伸'在C ++中添加一些方便和类型安全。例如,假设我的结构是
struct vector2D { float x, y; };
从许多来源,我已经收集到在C ++中扭曲这个结构的最安全的方法是将其子类化:
struct Vector2D: vector2D { ... };
到目前为止一切顺利。但是,我很难弄清楚如何将C结构重新解释为扩展版本。假设我有一个C函数
struct vector2D do_some_stuff(struct vector2D _a, struct vector2D _b) {
...
}
在这个函数中,我想使用C ++表示。由于struct vector2D
和Vector2D
的布局是相同的,我可以使用简单的演员,例如。
Vector2D a = static_cast<Vector2D>(_a)
但这似乎不起作用。使用构造函数会生成可怕的样板代码。
如果可能的话,这样做的正确方法是什么?
澄清:do_some_stuff
是一个C函数,仅用于从C代码调用。
答案 0 :(得分:2)
首选组合而不是继承。这会改变您的C ++ class Vector2D
以包含C struct vector2D
的实例并将其接口:
class Vector2D {
vector2D p;
public:
vector2D& getP() { return p; }
vector2D const& getP() const { return p; }
float& x() { return p.x; }
float& y() { return p.y; }
float const& x() const { return p.x; }
float const& y() const { return p.y; }
// ...
};
然后将C函数调用为:
Vector2D v1;
Vector2D v2;
...
auto p = do_some_stuff(v1.getP(), v2.getP());
答案 1 :(得分:2)
但是,我很难弄清楚如何将C结构重新解释为扩展版本。
嗯,这不是继承如何运作:你的女儿班是你母班的专业,所以你可以将Vector2D
解释为vector2d
,但不是相反。
考虑一下:如果扩展数据首先出现在哪里,它应该从哪里来?
你可以做的是实现一个构造函数或强制转换操作符,它使vector2d
初始化一个新的Vector2D
。
除此之外,我说你的整个努力都值得怀疑,因为它基于一个误解:你现在扩展的结构现在是一个C ++类,与C类型不同。
答案 2 :(得分:0)
经过一些实验,我已经想出了方法:
Vector2D v = *reinterpret_cast<Vector2D*>(&_v);
但是juanchopanza建议使用非会员功能可能是更好的方法。