2015-11-25 2 views
0

С надлежащим OOD, его редко приходится использовать dynamic_cast, но я использую его со следующим примером. Это правильный подход ? Идея кода, что классы Long и Double Numerics, и я решил добавить Numerics, включая смесь Double и Long, как показано в main().Dynamic_Cast in C++

class Numeric{ 
    virtual Numeric& (const Numeric& num)=0; 
} 

class Double: public Numeric{ 
    double data; 
    Numeric& operator+(const Numeric& num){ 
    //if Double type 
    if(Double* d = dynamic_cast<Double *>(num)){ 
     return Double(data+(Double &)num.data); 
     } 
    else{ //must be Long 
     return (doLongDoubleMath()); 
     } 
    } 
} 
class Long: public Numeric{ 
    long data; 
    Numeric& operator+(const Numeric& num){ 
    } 
} 

    int main(){ 
    Numeric &n1 = Double(1.1); 
    Numeric &n2 = Long(10); 
    Numeric &result = n1+n2; 

    return 0; 
    } 

Я хочу, чтобы иметь возможность смешивать различные типы, как добавить Double и Long..etc, Есть dynamic_cast правильного пути идти об этом, или вы можете придумать лучший способ?

+1

Вы уверены, что код компилируется? Попробуйте с помощью 'g ++ -Wall -Wextra -g' ... Ваша вторая строка выглядит подозрительной для меня ... –

+0

вам нужно предоставить оператор + перегрузка. Без этого, как вы можете назвать операцию добавления для определенных пользователем объектов? – Nandu

+4

Но вы должны сделать настоящий код. –

ответ

3

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

class Foo; 
class Bar; 
class Base { 
    public: 
     virtual Base& operator+(const Base& other) = 0; 

    protected: 
     virtual Base& addTo(Foo& other) const = 0; 
     virtual Base& addTo(Bar& other) const = 0; 
} 
class Foo : public Base { 
    public: 
     virtual Base& operator+(const Base& other) { 
      return other.addTo(*this); 
     } 
} 
... 

Конечно, это означает, что вы должны написать N^2addTo() функции, где N является числом классов что вы хотите иметь возможность добавлять взаимозаменяемые. Но это то же самое количество, что и if(Foo& foo = dynamic_cast<Foo&>(other)) {...}, - вы должны написать.

И двойная отправка скорее всего будет быстрее, потому что ваша лестница else if() проверит тип другого объекта несколько раз, а вызов виртуальной функции только один раз будет следовать указателю vtable, чтобы вызвать правильную функцию.

+0

Спасибо, я на самом деле уже попробовал двойную отправку, и я предположил ее «эквивалент» динамическому кастингу. Единственное, что я заметил при двойной диспетчеризации, - это обсуждение, если мне нужно вернуть указатель или ссылку со 2-ю диспетчерскими функциями, так как я не хочу, чтобы у пользователя была какая-либо память, поэтому, вероятно, это путь к переходу. – user1529412

+0

Проблема с возвратом ссылки и возвратом указателя одинаков: возвращаемый объект должен пережить вызов функции. То есть вы не можете вернуть указатель/ссылку на локальную переменную. Используете ли вы указатель или ссылку, не имеет значения. – cmaster

+0

Но если я верну указатель, указатель может быть NULL, тогда пользователь должен будет обработать это, Нет? – user1529412

Смежные вопросы