Почему я не могу разыменовать указатель на объект, который является элементом массива, использующим оператор косвенности?

Невозможно ли разыменовать указатель на объект, который хранится в массиве, используя оператор косвенности (разыменования), или я делаю что-то неправильно?

#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.