Перегрузка оператора косвенности в C ++ [Duplicate
-
27-10-2019 - |
Вопрос
Этот вопрос уже имеет ответ здесь:
Моя проблема простая. У меня есть шаблон класса, который имеет указатель на динамически выделенный тип. Я хочу перегрузить оператора косвенности так, чтобы ссылаться на экземпляр шаблона класса с помощью оператора ->, который я перенаправляю, как если бы я использовал указатель, содержащийся непосредственно.
template<class T>
class MyClass
{
T *ptr;
...
// created dynamic resource for ptr in the constructor
};
Создайте MyClass какого -то типа:
MyClass<SomeObject> instance;
Так что я хочу, чтобы вместо того, чтобы печатать:
instance.ptr->someMemberMethod();
Я просто печатаю:
intance->someMemberMethod();
Даже ты instance
это не указатель, он ведет себя так, как будто это указатель instance
содержит. Как преодолеть этот разрыв, перегружая оператора?
Решение
Вы можете просто перегрузить operator->
а также operator*
:
template<class T>
class MyClass
{
T* ptr;
public:
T* operator->() {
return ptr;
}
// const version, returns a pointer-to-const instead of just a pointer to
// enforce the idea of the logical constness of this object
const T* operator->() const {
return ptr;
}
T& operator*() {
return *ptr;
}
// const version, returns a const reference instead of just a reference
// to enforce the idea of the logical constness of this object
const T& operator*() const {
return *ptr;
}
};
Обратите внимание, что из -за разработного решения создателя языка вы не можете перегрузить .
оператор.
Кроме того, вы можете подумать, что operator*
перегрузил умножение оператор вместо оператора Dereference. Однако это не так, потому что оператор умножения берет один аргумент (в то время как оператор Dereference не принимает аргументов), и из -за этого компилятор может сказать, какой есть какой.
Наконец, обратите внимание, что operator->
возвращает указатель, но operator*
Возвращает ссылку. Легко их случайно запутать их.
Другие советы
Перегрузить ->
оператор:
template <typename T> class MyClass
{
T * p;
public:
T * operator->() { return p; } // #1
T const * operator->() const { return p; }
};
Обратите внимание, что оба Перегрузки не мутируют объект; Тем не менее, мы решаем сделать № 1 не консервативным, чтобы мы завещали постоянность объекта на точки. Иногда это называется «глубоким распространением константы» или чем -то в этом роде. Язык D занимает намного дальше.
Оператор доступа к участнику может быть перегружен, чтобы вернуть указатель на объект, который будет доступен:
T * operator->() {return ptr;}
T const * operator->() const {return ptr;}
Вы также можете захотеть оператора уважения, чтобы он чувствовал себя еще больше как указатель; Вместо этого это возвращает ссылку:
T & operator*() {return *ptr;}
T const & operator*() const {return *ptr;}