2017-01-22 6 views
1

Мне нужна помощь при перегрузке и наследовании оператора.C++ - Перегрузка и наследование оператора

class A { 
public: 
    virtual bool operator==(const A& a); 
}; 

class B : public A { 
public: 
    bool operator==(const B& b) { ... } 
}; 

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

+0

* «Я хочу быть в состоянии сделать что-то вроде этого». * - Это проблема сама по себе. Зачем вам это нужно? Это в основном приводит к проблеме двойной отправки; т.е. желаемая реализация функции больше не зависит от динамического типа * одного, а от * двух * объектов. Получение этого права дорого стоит с точки зрения сложности разработки и мало что дает. Если бы я был вами, я бы просто удалил оператора целиком. –

+1

Если вы не хотите сравнивать 'A' с' B', то почему 'A' предоставил виртуальный' operator ==() 'в первую очередь? – Peter

+0

Я хочу иметь список A и быть в состоянии выполнить операцию над B и C. – Znatte

ответ

0

Операторы - это просто функции, поэтому ваша проблема не связана с ними. То, что вы хотите здесь, называется множественной диспетчеризацией (в этом конкретном случае двойным, как правильно сказал христианин). Существует множество подходов к реализации и сложности выполнения, включая те, которые требуют поддержки языка (см., Например, параметры виртуальных функций и соответствующую бумагу от Bjarne Stroustrup).

Если вы хотите сделать это в основной C++, вы всегда можете посмотреть на моем родовом реализации и копировать то, что нужно: https://ideone.com/uGue2K

Использование кода:

// C inherits from A, both have a static initializer that registers them and their base class(es) 

struct print : Visitor2<A> 
{ 
    // Feel free to change the return type, but keep it consistent. 
    // Alternatively, you can call a lambda with the result. 
    static void v1(const A& a1, const A& a2, int i, int j) 
    { 
     std::cout << "A, A: "<< a1() << a2() << " " << i << " " << j << std::endl; 
    } 

    static void v2(const C& c1, const A& a2, int i, int j) 
    { 
     std::cout << "C, A: "<< c1() << a2() << " " << i << " " << j << std::endl; 
    } 

    // and so on... 

    print(int k_) 
    : k(k_) 
    { 
     add_visitor(v1, v2 /* ... */); 
    } 

    auto operator[](const A& a) { /* see in code */ }; 
}; 

int main() 
{ 
    print p(4); // p takes virtual A&, virtual A&, int, int. 

    const A& a = A(); 
    const A& b = B(); 

    p[a][a](1, 2); 
    p[c][a](2, 3); 
} 

Предложения приветствуются по коду и шаблону. Чтобы было легче следовать, operator[](const A&) посетителя реализован на месте, но это можно сделать полностью в Visitor2<A>.

Обратите внимание, что вместо не должно быть Visitor< Visitor<A> >, так как это не будет «возвращаться назад» к внешнему резольверу, если есть несколько внешних совпадений, а внутренняя попытка сначала не срабатывает. Это подчеркивает сложность множественной отправки (упомянутый христианин): вам нужно увидеть все потенциальные функции по всему миру. Ожидайте медленность и большие единицы компиляции; только реализуйте, если он находится в спецификации, и никаких ярлыков не найдено.

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