typedef struct без определения - PullRequest
       13

typedef struct без определения

2 голосов
/ 07 октября 2019

Я смотрю на заголовки библиотеки C ++, которую я использую, и есть такая строка:

typedef struct asdf_t asdf_t;

В источнике нет определения asdf_t. Что делает эта линия?

Ответы [ 2 ]

4 голосов
/ 07 октября 2019

Это то, что известно как объявление непрозрачной структуры ! Вероятно, в этом заголовке есть функции и / или классы, которые используют указатели на тип asdf_t - что разрешено в C ++ для неопределенных структур. Однако не будет (не может быть) объявленных переменных, членов класса или аргументов функции, которые являются экземплярами из asdf_t.

Так, например, ваш заголовок может позже объявитьследующий класс:

class GoodBoy {
public: GoodBoy();
       ~GoodBoy();
private:
    asdf_t* forMyEyesOnly; // Only a pointer - definition not needed!
}

Но он не может иметь это:

class BadGirl {
public BadGirl();
      ~BadGirl();
private:
    asdf_t notForAnyOneToSee; // Won't compile - would need definition.
}

Почему это сделано?

Обычно это потому, что создатели используемой вами библиотеки не хотят, чтобы вы знали детали этой структуры! Однако они должны предоставить такое «минимальное» определение, чтобы вы могли использовать классы и так далее , чтобы - по необходимости - использовать или ссылаться на эту структуру: так, например, в Реализация класса GoodBoy (т.е. частных исходных файлов, в которых для asdf_t дано полное определение ), можно было бы сделать так, чтобы конструктор и деструктор выполняли что-то вроде, скажем:

GoodBoy::GoodBoy() {
    forMyEyesOnly = new asdf_t; // Note: Neither the 'new' operation, nor...
}
GoodBoy::~GoodBoy() {
    delete forMyEyesOnly; // ...the 'delete' can compile without FULL DEFINITION!
}

Уточнение

Обычно такая непрозрачная структура объявляется просто: struct asdf_t;! Тем не менее, typedef struct asdf_t asdf_t; и typedef struct asdf_t; также являются допустимым синтаксисом (если немного странно).

Дальнейшее чтение

Есть хорошее (если немного старое) обсуждение переполнения стека на непрозрачных структурахи как их объявить, здесь .

2 голосов
/ 07 октября 2019

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

  • Например, вы можете определить прототип функции в тех же заголовочных файлах.
  • Вы можете определить указатель и скопировать / передать этот указатель (без доступа к его данным).

Это также известно как ADT (https://en.wikipedia.org/wiki/Abstract_data_type)

). Более подробно вы могли бы делать такие вещи, и компилятор (и программисты) будут знать, что ADT* это тип, отличный от примера доchar*:

typedef struct adt ADT;
void swap(ADT **a, ADT **b) {
   ADT *tmp = *a;
   *a = *b;
   *b = tmp;
}
...