Nano Hash - криптовалюты, майнинг, программирование

Как инициализировать член-структуру в списке инициализаторов класса C ++?

У меня есть следующие определения классов в С ++:

struct Foo {
  int x;
  char array[24];
  short* y;
};

class Bar {
  Bar();

  int x;
  Foo foo;
};

и хотел бы инициализировать структуру "foo" (со всеми ее членами) нулевым значением в инициализаторе класса Bar. Можно ли это сделать так:

Bar::Bar()
  : foo(),
    x(8) {
}

... ?

Или что именно делает foo (x) в списке инициализаторов?

Или структура даже автоматически инициализируется нулём компилятором?


  • Обратите внимание, что члены должны быть перечислены в списке инициализации в том же порядке, в котором они были объявлены, при этом вы сначала объявляете x, а в списке инициализации он занимает второе место. 17.11.2010

Ответы:


1

Прежде всего, вы должны (должны!) Прочитать это часто задаваемые вопросы о C ++, касающиеся POD и агрегатов. В вашем случае Foo действительно является классом POD, а foo() - инициализацией значения:

Инициализировать значение объекта типа T означает:

  • если T является типом класса (пункт 9) с конструктором, объявленным пользователем (12.1), то вызывается конструктор по умолчанию
    для T (и инициализация плохо сформирована, если T не имеет доступного конструктора по умолчанию);
  • если T - тип класса без объединения без конструктора, объявленного пользователем, то каждый нестатический член данных и компонент базового класса T инициализируется значением;
  • если T является типом массива, то каждый элемент инициализируется значением;
  • в противном случае объект инициализируется нулем

Так что да, foo будет инициализирован нулем. Обратите внимание, что если вы удалите эту инициализацию из Bar конструктора, foo будет только инициализирован по умолчанию:

Если для объекта не указан инициализатор, и объект относится к типу (возможно, cv-квалификационному), не относящемуся к классу POD (или его массиву), объект должен быть инициализирован по умолчанию; если объект имеет тип, уточненный константой, базовый тип класса должен иметь конструктор по умолчанию, объявленный пользователем. В противном случае, если для нестатического объекта не указан инициализатор, этот объект и его подобъекты, если таковые имеются, имеют неопределенное начальное значение;

17.11.2010
  • Что, если бы foo был определен как константный член? 10.09.2011

  • 2

    В стандартном C ++ вам нужно сделать ctor для Foo.

    struct Foo {
    
      Foo(int const a, std::initializer_list<char> const b, short* c)
        : x(a), y(c) {
        assert(b.size() >= 24, "err");
        std::copy(b.begin(), b.begin() + 24, array);
      }
    
      ~Foo() { delete y; }
    
      int x;
      char array[24];
      short* y;
    };
    
    class Bar {
    
      Bar() : x(5), foo(5, {'a', 'b', ..., 'y', 'z'},
        new short(5)) { }
    
      private:
    
      int x;
      Foo foo;
    };
    

    В C ++ 0x вы можете использовать единый список инициализации, но все же вам нужен dtor для Foo:

    class Bar {
    
      Bar() : x(5), foo{5, new char[24]{'a', 'b', ..., 'y', 'z'},
        new short(5)} { }
      ~Bar() { delete[] foo.array; delete foo.y;}
      }
      private:
    
      int x;
      Foo foo;
    };
    

    Чтобы по умолчанию инициализировать foo (как Bar() : foo(), x(8) { }), вам нужно указать Foo ctor по умолчанию.

    17.11.2010
  • Немного непонятно, где вы используете C ++ 03 против C ++ 0x. IIRC initializer_list является частью c ++ 0x. Кроме того, во втором кодовом блоке вы создали две утечки памяти. 17.11.2010
  • теперь у вас есть одно двойное удаление (foo.y) и одна утечка памяти (из new char[24], кроме того, я не уверен (но я могу ошибаться здесь), что это способ использования initializer_list) 17.11.2010
  • Был аналогичный случай, но struct Foo {int x,y; }, struct Goo : Foo { int z; }, struct Boo { Foo fs[2]; int x; } и статический массив констант Boos со списком инициализаторов static const Boo boos[] = { {{foo1, foo2},11}, {{foo3, foo6},15} } Дилемма для инициализации выглядит следующим образом: struct Goo(int x, int y) : Foo(x,y), мне нужен ctor для Foo, но нельзя использовать неагрегат (ctor) в списке инициализаторов ... 25.02.2016
  • Новые материалы

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

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..