Информация об изменениях

Сообщение Re: Оператора перегрузка от 10.03.2019 15:17

Изменено 10.03.2019 15:34 rg45

Re: Оператора перегрузка
Здравствуйте, Barbar1an, Вы писали:

  ccode
B>
B>template<class T> struct CObject
B>{
B>    CNexusObject *    Object = nullptr;

B>    CObject(){}
B>    CObject(CNexusObject * o) : Object(o)
B>    {
B>    }

B>    bool operator == (const CNexusObject * o) const 
B>    {
B>        return Object && Object == o;
B>    }

B>    T * operator->()
B>    {
B>        return dynamic_cast<T *>(Object);
B>    }

B>    operator T * () const
B>    {
B>        return dynamic_cast<T *>(Object);
B>    }
B>};

B>int main()
B>{
B>    CObject<CNexusObject> a;
B>    CNexusObject * b = nullptr;

            
B>    if(a == b)   // нужно чтобы вызывался мой оператор ==, вместо этого: error C2666: 'CObject<CNexusObject>::operator ==': 2 overloads have similar conversions
B>    {
B>    }
B>}
B>


B>как разрулить?


По сути вопроса: нужно просто вынести операторы сравнения за пределы класса, сделав их свободными функциями и предоставив все необходимые перегрузки.

Кроме того, хотелось бы обратить внимание на некоторые не очень хорошие моменты в коде: неявный преобразующий конструктор, неявный оператор преобразования к сырому указателю, открытый доступ к членам-данным. Ну и совсем мелочь — стиль именования членов-данных, затрудняющий чтение кода.

После исправления перечисленного, код мог бы выглядеть как-то так:

https://ideone.com/teMaOi

#include <iostream>
#include <cassert>

template<class T>
class CObject
{
private:
    T* m_Object = nullptr;

public:

    CObject() = default;
    explicit CObject(T* o) : m_Object(o) {  }

    T* get() const { return m_Object; }

    explicit operator bool() const { return m_Object != nullptr; }
    T* operator->() const { return m_Object; }
    T& operator* () const { assert(m_Object); return *m_Object; }
};

template <typename T>
bool operator == (const CObject<T>& lhs, const CObject<T>& rhs) { return lhs.get() == rhs.get(); }

template <typename T>
bool operator == (T* lhs, const CObject<T>& rhs) { return lhs == rhs.get(); }

template <typename T>
bool operator == (const CObject<T>& lhs, T* rhs) { return lhs.get() == rhs; }

template <typename T>
bool operator != (const CObject<T>& lhs, const CObject<T>& rhs) { return lhs.get() != rhs.get(); }

template <typename T>
bool operator != (T* lhs, const CObject<T>& rhs) { return lhs != rhs.get(); }

template <typename T>
bool operator != (const CObject<T>& lhs, T* rhs) { return lhs.get() != rhs; }

int main()
{
    class CNexusObject;

    CObject<CNexusObject> a;
    CNexusObject * b = nullptr;

    if(a == b)
    {
        std::cout << "Well done!" << std::endl;
    }
}
Re: Оператора перегрузка
Здравствуйте, Barbar1an, Вы писали:

  ccode
B>
B>template<class T> struct CObject
B>{
B>    CNexusObject *    Object = nullptr;

B>    CObject(){}
B>    CObject(CNexusObject * o) : Object(o)
B>    {
B>    }

B>    bool operator == (const CNexusObject * o) const 
B>    {
B>        return Object && Object == o;
B>    }

B>    T * operator->()
B>    {
B>        return dynamic_cast<T *>(Object);
B>    }

B>    operator T * () const
B>    {
B>        return dynamic_cast<T *>(Object);
B>    }
B>};

B>int main()
B>{
B>    CObject<CNexusObject> a;
B>    CNexusObject * b = nullptr;

            
B>    if(a == b)   // нужно чтобы вызывался мой оператор ==, вместо этого: error C2666: 'CObject<CNexusObject>::operator ==': 2 overloads have similar conversions
B>    {
B>    }
B>}
B>


B>как разрулить?


По сути вопроса: нужно просто вынести операторы сравнения за пределы класса, сделав их свободными функциями и предоставив все необходимые перегрузки.

Кроме того, хотелось бы обратить внимание на некоторые не очень хорошие моменты в коде: неявный преобразующий конструктор, неявный оператор преобразования к сырому указателю, открытый доступ к членам-данным. Ну и совсем мелочь — стиль именования членов-данных, затрудняющий чтение кода.

После исправления перечисленного, код мог бы выглядеть как-то так:

https://ideone.com/teMaOi

#include <iostream>
#include <cassert>

template<class T>
class CObject
{
private:
    T* m_Object = nullptr;

public:

    CObject() = default;
    explicit CObject(T* o) : m_Object(o) {  }

    T* get() const { return m_Object; }

    explicit operator bool() const { return m_Object != nullptr; }
    T* operator->() const { assert(m_Object); return m_Object; }
    T& operator* () const { assert(m_Object); return *m_Object; }
};

template <typename T>
bool operator == (const CObject<T>& lhs, const CObject<T>& rhs) { return lhs.get() == rhs.get(); }

template <typename T>
bool operator == (T* lhs, const CObject<T>& rhs) { return lhs == rhs.get(); }

template <typename T>
bool operator == (const CObject<T>& lhs, T* rhs) { return lhs.get() == rhs; }

template <typename T>
bool operator != (const CObject<T>& lhs, const CObject<T>& rhs) { return lhs.get() != rhs.get(); }

template <typename T>
bool operator != (T* lhs, const CObject<T>& rhs) { return lhs != rhs.get(); }

template <typename T>
bool operator != (const CObject<T>& lhs, T* rhs) { return lhs.get() != rhs; }

int main()
{
    class CNexusObject;

    CObject<CNexusObject> a;
    CNexusObject * b = nullptr;

    if(a == b)
    {
        std::cout << "Well done!" << std::endl;
    }
}