Открытое поле c ++ const против метода-получателя - PullRequest
7 голосов
/ 13 февраля 2011

Я хочу добавить уникальный идентификатор (в пределах одного сеанса) для каждого объекта определенного класса.Одним из решений является использование заводской функции, которая увеличивает статический счетчик.Более простое решение состоит в том, чтобы добавить этот счетчик к самому классу, например:

class fooWithUniqueId {
public:
    fooWithUniqueId() : id(next_id++) {...};        
    long id;

private:
    static long next_id = 0;
}

Недостатком, однако, является то, что поле id является общедоступным и может быть изменено вызывающей стороной, тем самым нарушая егоуникальность.Традиционно (ну, по крайней мере, на мой взгляд) это сделать id приватным и использовать функцию получения для доступа к нему, таким образом:

class fooWithUniqueId {
public:
    fooWithUniqueId() : id(next_id++) {...};                
    long getId() const { return id; };

private:
    long id;
    static long next_id = 0;
}

Но я рассматриваю другой подход.Я могу сделать id константным общедоступным полем класса:

class fooWithUniqueId {
public:
    fooWithUniqueId() : id(next_id++) {...};                
    const long id;

private:
    static long next_id = 0;
}

Мне нравится этот способ лучше, потому что мне не нужно постоянно вызывать getId() каждый раз, когда мне нужен идентификатор, я могу использовать идентификатор каквведите карту (поскольку конструкция копирования правильно инициализирует идентификатор объекта копирования).Единственный недостаток, о котором я могу подумать, это то, что я не могу реализовать назначения между fooWithUniqueId объектами, хотя в настоящее время эта функция мне не нужна.

  • Каковы плюсы и минусы каждого подхода (функция-получатель / поле const)?
  • Если я использую подход 'const', есть ли способ позже реализоватьоператор присваивания без нарушения кода?

Спасибо, Боаз

Ответы [ 2 ]

6 голосов
/ 13 февраля 2011

Я могу использовать идентификатор в качестве ключа на карте (поскольку конструкция копирования правильно инициализирует идентификатор объекта копирования)

Что вы подразумеваете под "правильно"?Конструктор копирования по умолчанию будет копировать идентификатор, независимо от того, хранится ли он в закрытой или общедоступной переменной-члене, и вы получите два объекта с одинаковым идентификатором.Это может быть не то, что вам нужно.

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

Я настоятельно рекомендую вам придерживаться лучших практик и использовать закрытое поле с функцией получения.

4 голосов
/ 13 февраля 2011

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

Тот факт, что член const отключает присваивание, кажется мне преимуществом. Если вы назначите один экземпляр другому, идентификаторы больше не будут уникальными!

...