Как вернуть разные классы из одной функции? - PullRequest
11 голосов
/ 10 февраля 2010

У меня есть вопрос, хотя он не ограничивается C ++. Как вернуть совершенно другой класс из одной функции?

f() {

in case one: return A;
in case two: return B;
in case three: return C;


}

Например, у меня есть два шара в пространстве, в соответствии с положением и размером, есть три ситуации, когда два шара пересекаются друг с другом, то есть не пересечение в точке, а и окружности. Как я могу вернуть другой класс в одной функции?

Спасибо.

Ответы [ 13 ]

0 голосов
/ 10 февраля 2010

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

0 голосов
/ 10 февраля 2010

Ограничение основано на объявленном типе возврата вашего метода.Ваш код гласит:

f() {
    in case one: return A;
    in case two: return B;
    in case three: return C;
}

Когда на самом деле компилятору требуется что-то вроде этого:

FooType f() {
    in case one: return A;
    in case two: return B;
    in case three: return C;
}

Должна быть возможность преобразовать A, B и C в тип FooType, обычночерез простое наследование, хотя я не буду вдаваться в различия между подклассами и подтипами.

Существуют подходы, которые могут обойти это.Вы можете создать класс или структуру (C ++), в которой есть поля для каждого различного типа возможного возврата, и использовать некоторое поле флага, чтобы указать, какое поле является фактическим возвращаемым значением.

class ReturnHolder {
    public int fieldFlag;
    public TypeA A;
    public TypeB B; 
    public TypeC C;
}

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

main(){

FooType *x = new FooType();
ReturnHolder ret = x.f();

switch (ret.fieldFlag)
    case: 1
        //read ret.A

    case: 2
        //read ret.B

    case: 3
        //read ret.C

}

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

0 голосов
/ 10 февраля 2010

На языках такого отражения легче добиться. В cpp, если у вас есть стандартный набор классов, которые нужно вернуть (указатели), создайте перечисление и верните значение перечисления. Используя это значение, вы можете определить тип класса. Это общий способ, если нет общего родительского класса

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...