Как я должен создавать члены C ++, которые зависят друг от друга? - PullRequest
4 голосов
/ 26 марта 2012

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

class Topic {
  Topic( Type T, String name );
};

class Reader {
  Reader (Topic, String name);
};

class Writer {
  Writer (Topic, String name);
};

Я хочу создать класс говорящего так:

Talker (Type T, String name);

И сгенерировать член Writer иЧитатель с конструктором.

Я разрываюсь между выполнением этого с указателями:

class Talker {
  Topic* m_Topic;
  Reader* m_Reader;
  Writer* m_Writer;

  Talker (Type T, String name) {
    m_Topic = new Topic (T, generateTopicName(name));
    m_Reader = new Reader (m_Topic, generateReaderName(name));
    m_Writer = new Writer (m_Topic, generateWriterName(name));
  }
};

По сравнению напрямую:

class Talker {
  Topic m_Topic;
  Reader m_Reader;
  Writer m_Writer;


  Talker (Type T, String name) :
    m_Topic(T, name),
    m_Reader(m_Topic, generateReaderName(name)),
    m_Writer(m_Topic, generateWriterName(name))
  {}
};

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

Какой лучший способ сделать что-то подобное, особенно если список объектов-членов становится длиннее?

Ответы [ 3 ]

5 голосов
/ 26 марта 2012

Такое решение не должно основываться на аргументе, предложенном вашим коллегой, так как это неверный аргумент.Вы можете контролировать порядок инициализации даже с элементами объекта - см. Мой последний абзац.Решение должно основываться на:

1) Функциональном - Вам требуются полиморфные типы?Будут ли наследоваться Topic, Reader и Writer?Если да, вы должны использовать указатели для предотвращения нарезки объектов.

2) Логический Является ли Talker истинным владельцем членов (объектов) или он просто указывает на некоторые объекты, которыеобщий для нескольких классов?

Старый ответ

Альтернативой является использование вместо указателей умных указателей.Таким образом, у вас все еще есть преимущества автоматического управления памятью.

Однако , аргумент вашего коллеги недействителен, и последний вариант неплох, если вы знаете свой C ++.Члены инициализируются в том порядке, в котором они объявлены в class.Таким образом, m_Topic будет инициализирован первым, m_Reader вторым и, наконец, m_Writer.Если важен порядок инициализации ( запах кода ), просто измените порядок членов в определении класса.

0 голосов
/ 26 марта 2012

Это действительно зависит от ваших требований

версия указателя более гибкая

  • Объекты могут быть нулевыми
  • Предметы можно обменять, забрать

но

  • Вы должны позаботиться о правильном уничтожении (хорошо, умные указатели помогут)
  • вам нужно больше памяти, по крайней мере, на 3 * 4 байта в среде 32-битной памяти, вероятно, больше из-за деталей реализации управления памятью, весьма вероятно, в два раза больше. Больно, когда у тебя много мелких предметов

Указатель модель довольно

  • положение автомобиля и колеса (сменное)

Модель члена довольно

  • ситуация с домом и комнатой (невозможно изменить комнату без изменения дома)
0 голосов
/ 26 марта 2012

Это сильно зависит от того, как вы будете использовать эти классы, но в целом, чем меньше выделений кучи, тем лучше, поэтому я склонен хмуриться на конструктор со всеми этими new s в нем.Является ли зависимость от порядка инициализации члена действительно проблемой?Я с трудом представляю, почему это так.

Если вы используете указатели, было бы разумно сделать это с умными, std::unique_ptr - канонический выбор.

...