Вопрос

В своем проекте я использую две разные библиотеки, и обе предоставляют базовый прямоугольник. struct.Проблема в том, что, похоже, нет способа вставить преобразование между типами, поэтому я не могу вызвать функцию в одной библиотеке с результатом функции в другой.Если бы я был автором любого из них, я мог бы создавать преобразования извне, я не могу.

библиотека а:

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

библиотека б:

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

Теперь я не могу сделать конвертер class, поскольку C++ будет искать преобразование только за один шаг.Вероятно, это хорошо, потому что появится много возможностей для создания новых объектов всех типов.

Я не могу создать оператор, который принимает struct от a и предоставляет объект class от b:

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

Итак, есть ли разумный способ обойти это?

редактировать:

Возможно, мне следует также отметить, что мне бы очень хотелось какое-то решение, которое сделает работу с результатом беспрепятственной, поскольку я не ожидаю, что буду таким программистом.(Хотя я согласен, олдскульное, явное преобразование было бы хорошим выбором.Другая ветка, reinterpret_cast та же проблема..)

редактировать2:

На самом деле ни одно из предложений не отвечает на мой актуальный вопрос. Конрад Рудольф кажется, правильно.C++ на самом деле не может этого сделать.Отстой, но это правда.(Если это имеет какое-то значение, я попробую создать подклассы, как это предложено КодированиеTheWheel.

Это было полезно?

Решение

Если вы не можете изменять структуры, у вас нет альтернативы написанию функции преобразования вручную, поскольку перегрузка операторов преобразования работает только внутри тела класса.Другого пути нет.

Другие советы

Создайте промежуточный тип прокладки "RectangleEx", а также определить пользовательские преобразования в/из сторонних типов строк.Всякий раз, когда вы обращаетесь к любому из API, делайте это через класс прокладки.

Другим способом было бы получить class от любого rect или Rectangle, и вставьте туда преобразования/конструкторы.

Не уверен, насколько это разумно, но как насчет чего-то вроде этого:

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

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

private:
    ...
};

Тогда вы можете просто обернуть каждый rectangle в R() и «правильное дело» произойдет.

В вашем случае это может быть неосуществимо, но я видел, как люди использовали небольшой препроцессор-foo для обеспечения совместимости типов.

Даже это предполагает, что вы создаете одну или обе библиотеки.

Также возможно, что вы вообще не хотите этого делать, а хотите пересмотреть какое-то раннее решение.Или нет.

Почему бы не что-то простое, например:(обратите внимание, что это может/вероятно не скомпилируется), но вы поняли...


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;

}

РЕДАКТИРОВАТЬ: Похоже, у нас с Коко та же идея.

Если structвнутри были одинаковыми, вы могли бы сделать reinterpret_cast;однако, поскольку похоже, что у вас есть 16-битные и 32-битные поля, вы, вероятно, застряли при преобразовании при каждом вызове или написании оболочек для всех функций одной из библиотек.

Может быть, вы могли бы попробовать это с перегрузкой операторов?(Может быть, оператор =, который не является методом вашего класса)?

Оператор Rect= (const Rect&,const прямоугольник&)

Подробнее об этом читайте в языке программирования C++ Бьярна Страуструпа или, может быть, на этой странице: http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top