2017-01-10 1 views
1

В чем разница между перегрузкой внутри и снаружи класса?Перегрузка оператора внутри и вне класса

class A{ 
    public: 
     bool operator==(const A *i){ 
     .... 
     .... 
     } 
}; 

против

bool operator==(const A *i , const A *j){ 
    .... 
    .... 
} 
+1

Если это возможно сделать снаружи, сделайте это снаружи. Но почему бы вам сравнить с указателем? Итак, вы хотите 'obj1 == & obj2'? Не имеет смысла. – DeiDei

+0

Попробуйте использовать либо. Они не делают то же самое. – juanchopanza

ответ

2

Сначала рассмотрим этот пример, используя свой класс (переформатирован в стиле я предпочитаю):

class A 
{ 
public: 
    auto operator==(A const* p) 
     -> bool 
    { 
     return true;  // Whatever. 
    } 
}; 

auto main() 
    -> int 
{ 
    A u{}, v{}; 
    A const c{}; 

    bool const r1 = (u == &v); // OK but needlessly annoying. 
    bool const r2 = (c == &v); // !Will not compile. 
} 

Здесь

  • Поскольку аргумент является указатель, код клиента должен применяться &.
  • Поскольку метод не является const, объекты, которые являются const, не могут сравниться.

Традиционный способ сделать это таким образом, чтобы передать аргумент по ссылке, и сделать метод const:

class B 
{ 
public: 
    auto operator==(B const& o) const 
     -> bool 
    { 
     return true;  // Whatever. 
    } 
}; 

auto main() 
    -> int 
{ 
    B u{}, v{}; 
    B const c{}; 

    bool const r1 = (u == v); // OK. 
    bool const r2 = (c == v); // OK. 
} 

Если определить сравнение вне класса, как это:

class B 
{}; 

auto operator==(B const& u, B const& v) 
    -> bool 
{ 
    return true;  // Whatever. 
} 

auto main() 
    -> int 
{ 
    B u{}, v{}; 
    B const c{}; 

    bool const r1 = (u == v); // OK. 
    bool const r2 = (c == v); // OK. 
} 

& hellip; затем

  • Гарантированное определение не зависит от внутренних деталей реализации класса B, которые, возможно, могут измениться в будущем.
  • Также первым аргументом может быть значение, которое неявно преобразуется в B.
  • Вы можете, если хочет, есть формальные аргументы различных типов, где класс появляется только во втором аргументе, как это:
auto operator==(int const u, B const& v) 
    -> bool 
{ 
    return true;  // Whatever. 
} 

Если вы решили разместить этот нечлен операторы, встроенные внутри определения класса, через механизм friend (так, чтобы они были найдены с помощью поиска ADL), тогда вы теряете преимущество первого пункта, но тогда у вас есть весь код, подходящий для использования класса, в определении класса :

class B 
{ 
public: 
    friend 
    auto operator==(B const& u, B const& v) 
     -> bool 
    { 
     return true;  // Whatever. 
    } 

    friend 
    auto operator==(int const u, B const& v) 
     -> bool 
    { 
     return true;  // Whatever. 
    } 
}; 

auto main() 
    -> int 
{ 
    B u{}, v{}; 
    B const c{}; 

    bool const r1 = (u == v); // OK. 
    bool const r2 = (c == v); // OK. 
    bool const r3 = (42 == v); // OK. 
} 
Смежные вопросы