Вложенные структуры

Насколько финализаторы идут:

  1. Они фактически бесполезны. Их, как гарантируют, не назовут своевременно, или действительно, вообще (если GC никогда не будет работать, ни один не будет никакие финализаторы). Это означает, что Вы обычно не должны полагаться на них.
  2. Финализаторы, как гарантируют, не будут идемпотентом. Сборщик "мусора" проявляет большую заботу, чтобы гарантировать, что это никогда не будет звонить finalize() несколько раз на том же объекте. С правильно написанными объектами это не будет иметь значения, но с плохо записанными объектами, вызов завершают, многократно может вызвать проблемы (например, удвоиться, выпуск собственного ресурса... отказывают).
  3. Каждый объект, который имеет finalize() метод, должен также обеспечить close() (или подобный) метод. Это - функция, которую необходимо вызывать. например, FileInputStream.close(). Нет никакой причины звонить finalize(), когда у Вас есть более соответствующий метод, который является , намеревался быть названным Вами.
11
задан Ankur 29 November 2009 в 14:31
поделиться

6 ответов

Код в вашем сообщении явно неполный, просто декларации, поэтому трудно сказать что-либо убедительное.

С очевидной разницей в том, что в C ++ тип внутренней структуры будет членом внешний тип структуры, в то время как в языке C оба типа структуры будут членами одной (включающей) области. (Кстати, вы намеревались объявить их локально в main ?)

Другими словами, в C ++ следующий код должен ссылаться на структуры как xx и xx :: yy , тогда как в C они будут просто xx и yy . Это означает, что дальнейший код будет выглядеть по-разному для C и C ++, и если он будет компилироваться на C ++, он не будет компилироваться на C и наоборот.

Добавлено: Язык C запрещает объявлять типы структур внутри других структур без объявления члена этого типа. Итак, объявление struct yy недопустимо в C и будет выдавать диагностическое сообщение компилятора. Если вы хотите, чтобы ваш код стал законным как в C, так и в C ++, вам придется объединить объявление struct yy с некоторым объявлением элемента данных. В вашем случае это может быть указатель q :

struct xx {
        int x;
        struct yy {
                char s;
                struct xx *p;
        } *q;
};

Вышеупомянутое допустимо как для C, так и для C ++ (с учетом различий, которые я объяснил ранее), но ваше исходное объявление не является законным для C.

d необходимо объединить объявление struct yy с некоторым объявлением элемента данных. В вашем случае это может быть указатель q :

struct xx {
        int x;
        struct yy {
                char s;
                struct xx *p;
        } *q;
};

Вышеуказанное является законным как для C, так и для C ++ (с учетом различий, которые я объяснил ранее), но ваше исходное объявление не является законным для C.

d необходимо объединить объявление struct yy с некоторым объявлением элемента данных. В вашем случае это может быть указатель q :

struct xx {
        int x;
        struct yy {
                char s;
                struct xx *p;
        } *q;
};

Вышеуказанное является законным как для C, так и для C ++ (с учетом различий, которые я объяснил ранее), но ваше исходное объявление не является законным для C.

18
ответ дан 3 December 2019 в 04:33
поделиться

Вот некоторые изменения (спасибо AndreyT):

Очевидно, вам нужно изменить заголовки для компиляции. Но даже тогда это кажется не стандартным C, как указал AndreyT . Тем не менее, некоторые компиляторы, такие как gcc, по-прежнему будут компилировать его, как ожидалось, и будут выдавать только предупреждение. Точно так же Microsoft , похоже, не слишком строго интерпретирует стандарт:

«Объявления структуры также могут быть указаны без декларатора, если они являются членами другой структуры или объединения»

Чтобы сделать его стандартным C вам нужно превратить ваше объявление "struct yy" в определение. Тогда ваш код будет действителен как на C, так и на C ++. Чтобы проиллюстрировать, что происходит, я переписал это, на мой взгляд, более понятным образом и добавил небольшой тест того, что происходит.

#include<stdio.h>
#include<stdlib.h>

typedef struct xx xx;
typedef struct yy yy;

struct yy{ char s; xx *p;};

struct xx{ int x; yy *q;};

int main(){
    xx test;
    test.q = (yy*)malloc(sizeof(yy));
    test.q->s = 'a';
    test.q->p = (xx*)malloc(sizeof(xx));
    test.q->p->x = 1; 
    test.q->p->q = (yy*)malloc(sizeof(yy));
    test.q->p->q->s = 'b';
    printf("s: %c\n", test.q->s);
    printf("x: %d\n", test.q->p->x);
    printf("s: %c\n", test.q->p->q->s);
    return 0;
}

Вы легко можете видеть, что у вас есть структура yy с указателем на xx, а структура xx имеет указатель на yy. Это эквивалентно тому, которое может быть записано в ansi-C:

#include<stdio.h>
#include<stdlib.h>

int main(){
    struct xx{
        int x;
        struct yy{
                    char s;
                    struct xx *p;
            } *q;   
            /*Here is the change to your example. You cannot have a structur 
              without a declactor inside of another structur! 
              Your version might due to compiler extensions still work*/
    };
    struct xx test;
    test.q = (struct yy*)malloc(sizeof(struct yy));
    test.q->s = 'a';
    test.q->p = (struct xx*)malloc(sizeof(struct xx));
    test.q->p->x = 1; 
    test.q->p->q = (struct yy*)malloc(sizeof(struct yy));
    test.q->p->q->s = 'b';
    printf("s: %c\n", test.q->s);
    printf("x: %d\n", test.q->p->x);
    printf("s: %c\n", test.q->p->q->s);
    return 0;
}

Я скомпилировал его с помощью gcc и следующих параметров:

gcc -ansi -pedantic -Wall -W -Wshadow -Wcast-qual -Wwrite-strings test.c -o

Оба варианта будут иметь одинаковый результат

s: a 
x: 1
s: b

Теперь, если вы хотите сделать то же самое в c ++, ваша структура не должна меняться, но для использования внутренней структуры вы должны вызвать оператор разрешения области (: :) следующим образом:

test.q = (xx::yy*)malloc(sizeof(xx::yy));
test.q->s = 'a';
test.q->p = (xx*)malloc(sizeof(xx));
test.q->p->x = 1; 
test.q->p->q = (xx::yy*)malloc(sizeof(xx::yy));
test.q->p->q->s = 'b';
printf("s: %c\n", test.q->s);
printf("x: %d\n", test.q->p->x);
printf("s: %c\n", test.q->p->q->s);
4
ответ дан 3 December 2019 в 04:33
поделиться

C не позволяет вам вкладывать объявление типа в определение функции. Кроме того, чтобы исключить предупреждение о том, что "ничего не объявляет", вам следует объединить объявления типа struct yy и member q . Следующее компилируется с gcc с max предупреждения на:

struct xx
{
        int x;
        struct yy
        {
                char s;
                struct xx *p;
        } *q;
};

int main()
{
  return 0;
}
2
ответ дан 3 December 2019 в 04:33
поделиться

Ну, cstdio нужно называть stdio.h. Что касается структуры, ключевое слово struct не требуется в C ++.

На самом деле вы определяете не элементы структуры, а элементы-указатели, поэтому кажется вероятным, что это должно работать в любом случае.

0
ответ дан 3 December 2019 в 04:33
поделиться

Я только что протестировал его с небольшими изменениями, и компилятор gcc

struct xx {
        int x;
        struct yy { char s; struct xx *p; };
        struct yy *q;
};

int main() { return 0; }

Compile with gcc

$ gcc test.c
test.c:3: warning: declaration does not declare anything

компилируется, но выдает предупреждение. Поскольку мой C слишком ржавый, ничего не могу сказать.

0
ответ дан 3 December 2019 в 04:33
поделиться

Основываясь на моем кратком исследовании и сообщении об ошибке, опубликованном Отто, кажется, что C не позволяет структурам быть контейнерами пространства имен общего назначения, такими как классы и структуры C ++ (естественно, потому что C даже не поддерживает классы). Таким образом, вы не можете вложить определения структур в C. Вам придется объявить внутреннюю структуру вне объявления внешней структуры следующим образом:

struct yy
{
        char s;
        struct xx *p;
};
struct xx
{
    int x;
    struct yy *q;
};

Я вижу, что структуры ссылаются друг на друга. Так что, если это возможно даже в C, вам, возможно, придется предварительно объявить более позднюю структуру со строкой вроде:

struct xx;

(над обоими другими объявлениями).

0
ответ дан 3 December 2019 в 04:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: