C ++ стиль кодирования геттеров / сеттеров

Я несколько раз сталкивался с этой проблемой в MacOS. Git чувствителен к регистру, но Mac - только сохранение случаев.

Кто-то фиксирует файл: Foobar.java и через несколько дней решает переименовать его в FooBar.java. Когда вы вытаскиваете последний код, он терпит неудачу с The following untracked working tree files would be overwritten by checkout...

. Единственный надежный способ, который я видел, который исправляет это:

  1. git rm Foobar.java
  2. Зафиксируйте его сообщением, которое вы не можете пропустить. git commit -m 'TEMP COMMIT!!'
  3. Pull
  4. Это вызовет конфликт, который заставит вас объединить конфликт, потому что ваше изменение удалило его, но другое изменение переименовано (следовательно, проблема). Примите свое изменение, которое является «удалением» git rebase --continue
  5. . Теперь оставьте свое обходное git rebase -i HEAD~2 и drop TEMP COMMIT!!
  6. Убедитесь, что файл теперь называется FooBar.java
65
задан CharlesB 26 April 2011 в 09:17
поделиться

6 ответов

Делать неконстантные поля плохой идеей, так как становится трудно принудительно устанавливать ограничения проверки ошибок и / или добавьте побочные эффекты к изменениям стоимости в будущем.

В вашем случае у вас есть поле const, поэтому вышеуказанные проблемы не являются проблемой. Основным недостатком сделать его открытым полем является то, что вы блокируете базовую реализацию. Например, если в будущем вы захотите изменить внутреннее представление на C-строку или строку Unicode или что-то еще, то вы нарушите весь клиентский код. С помощью метода получения вы можете преобразовать в унаследованное представление для существующих клиентов, предоставляя новые функции новым пользователям через новый метод получения.

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

46
ответ дан 24 November 2019 в 15:17
поделиться

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

В дополнение к этому, в C ++ особенно хорошей идеей является использование как getter, так и setter для члена с тем же именем , так как в будущем вы можете затем фактически изменить пару методов:

class Foo {
public:
    std::string const& name() const;          // Getter
    void name(std::string const& newName);    // Setter
    ...
};

В единственную общедоступную переменную-член, которая определяет оператор () () для каждого :

// This class encapsulates a fancier type of name
class fancy_name {
public:
    // Getter
    std::string const& operator()() const {
        return _compute_fancy_name();    // Does some internal work
    }

    // Setter
    void operator()(std::string const& newName) {
        _set_fancy_name(newName);        // Does some internal work
    }
    ...
};

class Foo {
public:
    fancy_name name;
    ...
};

Конечно, клиентский код нужно будет перекомпилировать, но никаких изменений синтаксиса не требуется! Очевидно, что это преобразование работает так же хорошо для константных значений, в которых требуется только геттер.

78
ответ дан 24 November 2019 в 15:17
поделиться

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

class Foo {
    public:
        const std::string& getName() const {return name_;}
    private:
        const std::string& name_;
};

Обратите внимание, что если вы измените getName () чтобы вернуть вычисленное значение, он не может вернуть const ref. Это нормально, потому что это не потребует каких-либо изменений в вызывающих программах (по модулю перекомпиляции).

5
ответ дан 24 November 2019 в 15:17
поделиться

Кроме того, в C ++ несколько странно иметь ссылочный член const. Вы должны назначить его в списке конструкторов. Кому принадлежит собственно память об этом объекте и какова его продолжительность?

Что касается стиля, я согласен с другими, что вы не хотите выставлять своих рядовых. :-) Мне нравится этот шаблон для сеттеров / геттеров

class Foo
{
public:
  const string& FirstName() const;
  Foo& FirstName(const string& newFirstName);

  const string& LastName() const;
  Foo& LastName(const string& newLastName);

  const string& Title() const;
  Foo& Title(const string& newTitle);
};

Таким образом, вы можете сделать что-то вроде:

Foo f;
f.FirstName("Jim").LastName("Bob").Title("Programmer");
21
ответ дан 24 November 2019 в 15:17
поделиться

Избегайте открытых переменных, за исключением классов, которые по сути являются структурами в стиле C. Это просто плохая практика.

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

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

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

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

Когда бы это ни было действительно важно для простоты написания, входите в более безопасная привычка.

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

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

Когда бы это ни было действительно важно для простоты написания, входите в более безопасная привычка.

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

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

Когда бы это ни было действительно важно для простоты написания, входите в более безопасная привычка.

3
ответ дан 24 November 2019 в 15:17
поделиться

Из теории шаблонов проектирования; «инкапсулировать то, что меняется». При определении «добытчика» существует хорошая приверженность вышеуказанному принципу. Таким образом, если представление-представление элемента изменится в будущем, элемент может быть «массирован» перед возвратом из «получателя»; подразумевает отсутствие рефакторинга кода на стороне клиента, где выполняется вызов getter.

С уважением,

0
ответ дан 24 November 2019 в 15:17
поделиться
Другие вопросы по тегам:

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