2013-12-26 1 views
0

У меня есть класс Property, содержащий данные типа Matrix и который перегружает операторы ->, * и &, Matrix будучи еще один класс шахты. Перегрузки обеспечивают прямой доступ к данным, например.Перегружен -> и *: как получить доступ к начальному классу?

Property myProp; 
myProp->trace(); 

Приведенный выше код позволяет вычислить след матрицы непосредственно из Property, содержащей его, и без того, чтобы сначала получить данные: удобный.

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

myProp->registerCallback(myCallback); 

Моя проблема заключается в том, что operator-> возвращает ссылку на Matrix, следовательно registerCallback вызывается на классе матрицы, а не на Property. Поскольку я также перегружал других операторов * и &, кажется, что я больше не могу назвать функции-члены от Property.

Следовательно, мой вопрос: есть ли какой-либо трюк для работы с базовым типом после того, как оператор был перегружен, чтобы вернуть другой тип?

Большое спасибо!

+4

Перегрузка унарного оператора & является одним из тех умных трюков, которые могут принести больше вреда, чем пользы. – fasked

ответ

1

Вы должны все еще быть в состоянии вызывать функции в Property с оператором . ...

Property myProp; 
myProp->trace(); 
myProp.registerCallback(myCallback); 

У вас есть незначительные недоразумения. Если вы перегружаете operator* и operator->, тогда вы пытаетесь работать как указатель. Эта ситуация часто возникает при использовании итераторов. Методы итератора вызываются с . следующим образом.

Я понятия не имею, почему вы хотите перегружать operator&; для достижения того же самого, что и у fasked operator&, просто используйте &(*myProp). Кроме того, &myProp должен предоставить вам адрес myProp, а не его объект.

+1

Hum hum ... Это так просто, что это неловко;) Спасибо в любом случае! – arennuit

+0

Все в порядке. Это часть привычки к этому. –

3

В C++ 11 есть функция std::addressof. Кроме того, библиотека boost обеспечивает функцию addressof. Пример:

#include <iostream> 
#include <memory> 

struct Data 
{ 
    void foo() { 
     std::cout << "Data::foo" << std::endl; 
    } 
}; 

template <typename T> 
class Property 
{ 
public: 
    Property() : data(new T) {} 
    ~Property() { delete data; } 

    T** operator &() { 
     return &data; 
    } 

    T* operator->() { 
     return data; 
    } 

    void foo() { 
     std::cout << "Property::foo" << std::endl; 
    } 

private: 
    T *data; 
}; 

int main() 
{ 
    Property<Data> p; 

    p->foo(); 
    std::addressof(p)->foo(); 
} 
+0

Я не знал об этом, спасибо! – arennuit

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