Почему я не могу разыменовать указатель на объект, который является элементом массива, использующим оператор косвенности?
Невозможно ли разыменовать указатель на объект, который хранится в массиве, используя оператор косвенности (разыменования), или я делаю что-то неправильно?
#include <iostream>
class A {
public:
virtual void test() {
std::cout << "A\n";
}
};
class B : public A {
public:
void test() {
std::cout << "B\n";
}
};
int main() {
A* v[2];
v[0] = new A();
v[1] = new B();
v[0]->test();
*(v[1]).test(); // Error! If the arrow operator is used instead
// though, the code compiles without a problem.
return 0;
}
Вот ошибка, которую я получаю:
$ g++ -std=c++11 test.cpp && ./a.out
test.cpp: In function ‘int main()’:
test.cpp:26:13: error: request for member ‘test’ in ‘v[1]’, which is of
pointer type ‘A*’ (maybe you meant to use ‘->’ ?)
*(v[1]).test();
Ответы
Ответ 1
В соответствии с Приоритет оператора operator.
(оператор доступа к членству) имеет более высокий приоритет, чем operator*
(оператор косвенного/разыменования) поэтому *(v[1]).test();
эквивалентно *((v[1]).test());
, что неверно. (Вы не можете вызвать test()
на v[1]
, который A*
через opeartor.
.)
Измените его на
(*v[1]).test();
Ответ 2
Правильный способ:
(*v[1]).test();
Здесь вы сначала индексируете массив и получаете указатель (v[1]
), затем вы разыгрываете указатель (*v[1]
) и, наконец, вызываете метод по значению объекта.
В вашем примере вы сначала попытались вызвать test
, используя .
on v[1]
, который является указателем. И только после этого вы разыменовали возвращаемое значение метода, что также бессмысленно, поскольку test
возвращает void.