2013-11-22 3 views
4

У меня возникли некоторые проблемы с пониманием использования указателей в этой программе:Что с указателями на C++?

#include<iostream.h> 
class ABC 
{ 
    public: 
     int data; 
     void getdata() 
     { 
      cout<<"Enter data: "; 
      cin>>data; 
      cout<<"The number entered is: "<<data; 
     } 
}; 
void main() 
{ 
    ABC obj; 
    int *p; 
    obj.data = 4; 
    p = &obj.data; 
    cout<<*p; 
    ABC *q; 
    q = &obj.data; 
    q->getdata(); 
} 

Я получаю все, до следующего шага: ABC *q;
Что это делать? В моей книге говорится, что это указатель класса (он очень расплывчатый с патетической грамматикой). Но что это значит? Указатель, указывающий на адрес класса ABC?

Если это так, то следующий шаг меня смущает. q = &obj.data;
Таким образом, мы указываем этот указатель на местоположение данных, который является переменной. Как это вписывается ABC *q;?

И последний шаг. Что делает q->getdata();? В моей книге говорится, что это указатель на оператор-функцию члена ', но не дает никаких объяснений.

Рад помочь!

+30

Бросьте эту книгу. – unwind

+2

Я предполагаю, что 'q = & obj.data' равно' q = & obj'? – this

+0

Во-первых, q является указателем на объект класса ABC, поэтому 'q = & obj'. Во-вторых, 'q-> getdata()' вызовет метод для этого экземпляра ABC – jandresrodriguez

ответ

3
ABC * q 

Эта инструкция создает для указания фрагмента памяти, где находится экземпляр класса ABC. Например:

q = new ABC(); 

Это создает экземпляр ABC и сохраняет адрес этого экземпляра в переменной q.

ABC abc; 
q = &abc; 

Это конкретизирует ABC автоматически (что означает, что компилятор заботится о выделении и освобождении этого экземпляра) и сохраняет адрес для данного класса в д.

Кроме того, -> не является указатель на элемент функции оператор. Это лишь короткий путь писать что-то еще:

a -> b 

приравнивает

(*a).b 

Если вы знаете, что a указывает на экземпляр класса (или структуры, например, то, что в C++ является более менее в) и вы хотите получить доступ к члену (полю или метод) этого экземпляра, вы можете быстро написать a->b = 5; или a->DoSth(); вместо (*a).b = 5; или (*a).DoSth();.

+0

Я думаю, что OP был смущен 'q = & obj.data'. – this

+2

Fun fact '->' - не единственный оператор C++ с таким простым определением. Оператор 'a [b]' индекса массива определяется как '* ((a) + (b))', что означает, что 'b [a]' является столь же достоверным. – Mgetz

+0

Это было довольно информативно, спасибо! – mikhailcazi

5

Эта книга является неправильным, потому что она должна быть:

ABC *q; 
q = &obj; 
q->getdata(); 

Или с помощью Int указатель:

ABC *q; 
int *qq; 
qq = &obj.data; 
q = &obj; 
q->getdata(); 
+0

Работа ' qq' уже выполняется 'p', хотя. – mikhailcazi

+0

фактически потому, что int-данные являются первым членом класса & obj и & obj.data представляют один и тот же адрес. Так что это совершенно верно – Pandrei

+1

Нет, это не совсем так. Компилятор будет жаловаться, что он не может преобразовать int * в ABC *. Да, они будут одного и того же адреса, но они не одного типа, поэтому исходный код не будет компилироваться. – Speed8ump

2

q = &obj.data часть, как заявил 'Хромой-вверх-утка' не сложите:

Ваш указатель:

ABC *q; 

Является переменной, обычно 32 или 64 бит.Он может содержать адрес памяти объекта, в данном случае типа ABC

Таким образом, у вас есть этот объект в obj.

Для того, чтобы указатель фактической «точка» для этого объекта, вам нужно присвоить значение адреса памяти для указателя с «адрес оператора» &, как это:

q = &obj; 

q теперь показывает к объекту obj. Вы можете получить доступ к этому obj объекту с

q-> 

Теперь q->getdata() будет вызывать функцию getdata в obj.

+0

"' q' теперь указывает на объект 'obj.data'." Вы уверены, что? :-) –

+1

@ user1158692: thanks :), я был смущен из-за «плохой книги» – Stefan

2
ABC obj; 
ABC *q; 
q = &obj.data; 

не следует компилировать.

Более логично было бы

q = &obj; 

, который присваивает адрес obj (экземпляр класса ABC) на указатель-на-ABC называется q.

Как только это будет сделано, если вы хотите позвонить GetData на д использовании

q -> getdata(); 

... потому что д является указателем. Сравните это с тем, что вы могли бы сделать с obj (который является переменной стека)

obj.getdata(); 

Та же функция, называется по-разному.

+0

на самом деле он компилируется, и все отлично. проблема будет в случае следующего утверждения: q = & (obj.data), потому что теперь вы назначаете int * для ABC *, и компилятор не может выполнять неявный перевод. – Pandrei

+0

@Pandrei Нет, он не компилируется. Я попробовал. Компилятор выделил следующую строку: 'q = & obj.data;' и дал мне следующую ошибку: «Невозможно преобразовать« int * »в« ABC * ». – mikhailcazi

+0

Ввод скобок не будет иметь никакого значения. Компилятор примет 'obj.data' как один элемент даже без скобок. Он не будет указывать 'q' просто' obj' только потому, что вы не включили все это в скобки. – mikhailcazi

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