简体   繁体   English

如何在C ++中转换类型?

[英]How can I convert types in C++?

I'm using two different libraries in my project, and both of them supply a basic rectangle struct . 我在项目中使用了两个不同的库,它们都提供了基本的矩形struct The problem with this is that there seems to be no way to insert a conversion between the types, so I can't call a function in one library with the result from a function in the other. 这样做的问题是,似乎没有办法在类型之间插入转换,因此我不能在一个库中调用函数,而将另一个函数的结果调用。 If I was the author of either of these, I could create conversions, from the outside, I can't. 如果我是这两种方法的作者,那么我可以从外部创建转换,但是我不能。

library a: 库a:

typedef struct rectangle { sint16 x; sint16 y; uint16 w; uint16 h; } rectangle;

library b: 库b:

class Rect {
  int x; int y; int width; int height;
  /* ... */
};

Now, I can't make a converter class , because C++ will only look for a conversion in one step. 现在,我无法创建转换器class ,因为C ++只会一步一步地寻找转换。 This is probably a good thing, because there would be a lot of possibilities involving creating new objects of all kinds of types. 这可能是一件好事,因为创建各种类型的新对象会涉及很多可能性。

I can't make an operator that takes the struct from a and supplies an object of the class from b : 我无法使运算符从a接受struct并从b提供class的对象:

foo.cpp:123 error: ‘operator b::Rect(const rectangle&)’ must be a nonstatic member function

So, is there a sensible way around this? 那么,有没有解决这个问题的明智方法呢?

edit: 编辑:

I should perhaps also point out that I'd really like some solution that makes working with the result seamless, since I don't expect to be that coder. 我也许还应该指出,我真的很想要一些可以无缝处理结果的解决方案,因为我不希望成为那种编码器。 (Though I agree, old-school, explicit, conversion would have been a good choice. The other branch, reinterpret_cast has the same problem..) (尽管我同意,老式的,显式的转换将是一个不错的选择。另一个分支reinterpret_cast也存在相同的问题。)

edit2: 编辑2:

Actually, none of the suggestions really answer my actual question, Konrad Rudolph seems to be correct. 实际上,所有建议都无法真正回答我的实际问题, 康拉德·鲁道夫Konrad Rudolph)似乎是正确的。 C++ actually can't do this. C ++实际上无法做到这一点。 Sucks, but true. 糟透了,但事实如此。 (If it makes any difference, I'm going to try subclassing as suggested by CodingTheWheel . (如果有什么不同,我将尝试按照CodingTheWheel的建议进行子类

Create an intermediate shim type " RectangleEx ", and define custom conversions to/from the 3rd-party string types. 创建一个中间填充类型“ RectangleEx ”,并定义到/自第三方字符串类型的自定义转换。 Whenever you speak to either API, do so through the shim class. 每当您使用这两个API进行交谈时,都可以通过shim类进行操作。

Another way would be to derive a class from either rect or Rectangle , and insert conversions/constructors there. 另一种方法是从rectRectangle派生一个class ,然后在其中插入转换/构造函数。

Not sure how sensible this is, but how about something like this: 不知道这有多明智,但是像这样的事情如何:

class R
{
public:
    R(const rectangle& r) { ... };
    R(const Rect& r) { ... };

    operator rectangle() const { return ...; }
    operator Rect() const { return ...; }

private:
    ...
};

Then you can just wrap every rectangle in R() and the "right thing" will happen. 然后,您可以将每个rectangle都包裹在R() ,然后“正确的事情”就会发生。

If you can't modify the structures then you have no alternative to writing a manual conversion function because overloading conversion operators only works within the class body. 如果您不能修改结构,那么您除了编写手动转换函数外别无选择,因为重载转换运算符仅在类体内起作用。 There's no other way. 没有别的办法了。

It may not be feasible in your case, but I've seen people employ a little preprocessor-foo to massage the types into compatibility. 在您的情况下,这可能不可行,但是我已经看到人们使用一些预处理器-foo来使类型兼容。

Even this assumes that you are building one or both libraries. 即使这样,也假设您正在构建一个或两个库。

It is also possible that you don't want to do this at all, but want to re-evaulate some early decision. 您也可能根本不想这样做,但想重新评估一些早期决定。 Or not. 或不。

If the struct s were the same internally, you could do a reinterpret_cast ; 如果内部的struct相同,则可以执行reinterpret_cast ; however, since it looks like you have 16-bit vs 32-bit fields, you're probably stuck converting on each call, or writing wrappers for all functions of one of the libraries. 但是,由于看起来您具有16位和32位字段,因此您可能在每次调用时都进行转换,或者为其中一个库的所有功能编写包装器。

Why not something simple like this: (note this may/probably won't compile) but you get the idea... 为什么不这样简单:(请注意,这可能/可能不会编译),但是您知道了...


private Rect* convert(const rectangle& src)
{
    return new Rect(src.x,src.y,src.w,src.h);
}
int main()
{
    rectangle r;
    r.x = 1;
    r.y = 2;
    r.w = 3;
    r.h = 4;

    Rect* foo = convert(&r);
    ...
    delete foo;

}

EDIT: Looks like koko's and I have the same idea. 编辑:看起来像科科的和我有相同的想法。

Maybe you could try it with operator overloading ? 也许您可以尝试使用运算符重载? (Maybe a = operator which is not a method of your class) ? (也许是=运算符,它不是您的类的方法)?

Rect operator= (const Rect&,const rectangle&) 矩形运算符=(常量矩形和常量矩形)

More about this in the C++ programming language by Bjarne Stroustrup or maybe on this page: http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html 有关Bjarne Stroustrup的C ++编程语言的更多信息,或在以下页面上: http//www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM