У меня есть класс Property
содержащий данные типа Matrix
и который перегружает операторы ->
, *
и &
, Matrix
- еще один класс. Перегрузки обеспечивают прямой доступ к данным, например
Property myProp;
myProp->trace();
Вышеприведенный код позволяет вычислить трассировку матрицы непосредственно из Property
содержащего ее, и без необходимости сначала получать данные: удобно.
Теперь я хочу добавить обратный вызов к моему Property
которое вызывается при обновлении Property
. Для этого я хотел бы написать что-то вроде:
myProp->registerCallback(myCallback);
Моя проблема заключается в том, что operator->
возвращает ссылку на Matrix
, поэтому registerCallback
operator->
в классе matrix, а не в Property
. Поскольку я также перегружал другие операторы *
и &
, кажется, я больше не могу вызывать функции-члены из Property
.
Поэтому мой вопрос: есть ли какой-либо трюк для работы с базовым типом после того, как оператор был перегружен, чтобы вернуть другой тип?
Большое спасибо!
Вы все равно должны иметь возможность вызывать функции в Property
с помощью .
оператор...
Property myProp;
myProp->trace();
myProp.registerCallback(myCallback);
У вас небольшое недоразумение. Если вы перегрузите operator*
и operator->
тогда вы пытаетесь работать как указатель. Эта ситуация часто возникает при использовании итераторов. Вызывается метод итератора .
как это.
Я понятия не имею, почему вы хотите перегрузить operator&
; для достижения того же самого действия, что и у operator&
fasked operator&
, просто используйте &(*myProp)
. Кроме того, &myProp
должен предоставить вам адрес myProp
, а не его содержащийся объект.
В С++ 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();
}