2012-05-03 4 views
0

я прочитал книгу, которая дает пример файла .h, что равно интерфейс очереди в Java:C++/аргументы в h. файл

void InitQueue(Queue* pQueue, int iSize); 
bool Insert(Queue* pQueue, const Item* pItem); 
bool Extract(Queue* pQueue, Item** pItem); 
bool GetFirst(const Queue* pQueue, Item** pItem); 
bool IsFull(const Queue* pQueue); 
bool IsEmpty(const Queue* pQueue); 

Я не понял две вещи:

  1. Почему в Extract, GetFirst второй аргумент имеет тип Item**, а не Item*? Что значит, когда мы говорим об этом?
  2. Почему в некоторых функциях (IsFull, IsEmpty, ..) мы получаем аргумент const Queue*, а не просто Queue*?
+0

Была ли книга, написанная [2-звездным программистом] (http://c2.com/cgi/wiki?ThreeStarProgrammer)? – Mysticial

+2

Действительно ли это C++? Это похоже на то, что делалось в C. (Опять же, возможно, это какая-то техника, о которой я не знаю) – Pubby

+0

Потому что они хотят иметь возможность изменять указатель, который вы передаете функции. Если бы это был только «Item * pItem», вы бы передали копию своего указателя, который, если они изменили его внутри функции, не будет виден вне функции –

ответ

3

IsFull() и IsEmpty() принимают аргументы const, поскольку подразумевают, что они не изменят объект Queue; он является постоянным и не будет изменен.

экстракт и GetFirst использовать ** из-за этого:

int a;   // Declares an int 
a = 2;   // Sets a to 2 
int *b = &a;  // Declares a pointer pointing to that int 
*b = 4;   // Sets a to 4 
int **c = &b; // Declares a pointer pointing to that pointer to that int 
**c = 6;   // Sets a to 6 

Если бы я пройти с в функции:

int global_var; 

int main() { 
    modify_ptr(c); 
} 

void modify_ptr(int **ptr) 
{ 
    *ptr = &global_var; 
} 

Указатель я только что прошел в сам был изменен; ** c теперь указывает на global_var вместо a.

Причина, по которой вы передаете эти указатели в getfirst и extract, состоит в том, что они являются функциями «getter» - вы хотите, чтобы они вернули указатель на данные. Поэтому они должны иметь возможность возвращать указатель, а метод, который они используют, - передать указатель на указатель, как в приведенном выше примере, чтобы они могли модифицировать то, что вы передаете, чтобы указать на правильный элемент.

2

Почему в Extract, GetFirst Второй аргумент типа Item** и не Item*? Что значит, когда мы написали такую ​​вещь?

Чтобы указатель мог быть изменен внутри функции.
Скорее всего, это означает, что указатель Item будет передан вызывающим абонентом, но будет выделен внутри функции. Вы не можете сделать этого, просто передав указатель по значению, потому что он будет выделять память на копию указателя, а не на исходный указатель.

Трудно сказать, почему программист использует эту семантику звонящего, передавая указатель и функцию, выделяя его. В самом деле, можно было бы ожидать механизма исток-источник.

Почему в некоторых функциях (IsFull, IsEmpty, ..) мы получаем в качестве аргумента const Queue*, а не просто Queue*?

const correctness!
Он указывает пользователю функции, что данные, указанные в данных, не будут изменены внутри функции.

1

Почему в экстракт, GetFirst Второй аргумент имеет тип Item **, а не Item *? Что значит, когда мы говорим об этом?

Это выходы. Похоже, что очередь содержит кучу указателей на элементы. Поскольку это указатель, я бы сделал Extract и GetFirst взял только один аргумент и вернул указатель. Нулевой указатель указывает на сбой. Разработчики этого не сделали. Вместо этого они использовали старую парадигму стиля С. Зачем? Кто знает. Это не лучший способ написать их.

Почему в некоторых функциях (IsFull, IsEmpty, ..) мы получаем аргумент const Queue *, а не просто Queue *?

Отметить аргумент как const, который указывает пользователю код, что функция ничего не сделает с содержимым аргумента. Маркировка таких невозмущенных ссылок и аргументов указателя как const - хорошая практика программирования.

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