Популярны ли функции get и set у программистов на C ++? - PullRequest
32 голосов
/ 10 апреля 2009

Изначально я из мира C # и изучаю C ++. Мне было интересно узнать о функциях get и set в C ++. В C # они довольно популярны, а такие инструменты, как Visual Studio, способствуют их использованию, делая их очень простыми и быстрыми в реализации. Однако в мире C ++ это не так.

Вот код C # 2.0:

public class Foo
{
    private string bar;

    public string Bar
    {
        get { return bar; }
        set { bar = value; }
    }
}

Или в C # 3.0:

public class Foo { get; set; }

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

Теперь, поскольку я так привык к этому, я чувствую, что должен перенести эту привычку на свой код C ++, но действительно ли это необходимо? Я не вижу, как это делается так часто, как с C #.

В любом случае, вот C ++ из того, что я собираю:

class Foo
{
public:
    std::string GetBar() const; // Thanks for the tip Earwicker.
    void SetBar(std::string bar);
private:
    std::string bar;
}

const std::string Foo::GetBar()
{
    return bar;
}

void Foo::SetBar(std::string bar)
{
    // Also, I always wonder if using 'this->' is good practice.
    this->bar = bar;
}

Теперь, для меня это похоже на большую работу ног; Учитывая использование инструментов Visual Studio, реализация C # заняла бы буквально секунды, а ввод C ++ занял у меня намного больше времени - я чувствую, что это не стоит усилий, особенно когда альтернатива имеет 5 строк:

class Foo
{
public:
    std::string Bar;
}

Из того, что я понял, вот преимущества:

  • Вы можете изменить детали реализации функций get и set, поэтому вместо возврата личного поля вы можете вернуть что-то более интересное.
  • Вы можете позже удалить get / set и сделать его доступным только для чтения / записи (но для общедоступного интерфейса это не очень хорошо).

И недостатки:

  • Печатает целую вечность, действительно ли это стоит усилий? Вообще говоря. В некоторых случаях преимущества оправдывают свои усилия, но я имею в виду, говоря словами «хорошая практика», правда?

Ответ:

Почему я выбрал ответ с меньшим количеством голосов ? На самом деле я был очень близок к выбору ответа veefu ; однако мое личное мнение (которое, по-видимому, является спорным) заключается в том, что ответ на вопрос о вареном пудинге.

Ответ, который я выбрал, с другой стороны, кажется, спорит обе стороны; Я думаю, что геттеры и сеттеры являются злом, если используются чрезмерно (я имею в виду, когда это не нужно и нарушит бизнес-модель), но почему бы нам не иметь функцию с именем GetBalance()?

Конечно, это будет гораздо более универсальным, чем PrintBalance(); Что, если я хотел показать это пользователю иначе, чем того хотел класс? Теперь, в некотором смысле, GetBalance() может быть недостаточно релевантным, чтобы утверждать, что «геттеры и сеттеры хороши», потому что у него нет (или, возможно, не должно ) иметь сопровождающий сеттер, и говорить о что, функция с именем SetBalance(float f) может быть плохой (на мой взгляд), потому что это подразумевает, что для реализации функции необходимо манипулировать учетной записью вне класса, что не очень хорошая вещь.

Ответы [ 14 ]

1 голос
/ 10 апреля 2009

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

0 голосов
/ 21 апреля 2009

Если вы используете C ++ / CLI в качестве вашего варианта C ++, то у него есть встроенная поддержка свойств в языке, поэтому вы можете использовать

property String^ Name;

Это то же самое, что и

String Name{get;set;}

в C #. Если вам нужен более точный контроль над методами get / set, вы можете использовать

property String^ Name
{
   String^ get();
   void set(String^ newName);
}

в шапке и

String^ ClassName::Name::get()
{
   return m_name;
}

void ClassName::Name::set(String^ newName)
{
   m_name = newName;
}

в файле .cpp. Я не могу вспомнить, но думаю, что вы можете иметь разные права доступа для методов get и set (public / private и т. Д.).

Colin

0 голосов
/ 10 апреля 2009

Компилятор выдаст set_ и get_, если вы определите свойство, так что на самом деле просто сохраните некоторые данные.

Это было интересное обсуждение. Это что-то из моей любимой книги "CLR via C #".

Вот что я цитировал.

Лично мне не нравятся свойства и я бы хотел, чтобы их не было поддерживается в Microsoftm.NET Фреймворк и его программирование языки. Причина в том, что свойства выглядят как поля, но они методы. Это было известно вызвать феноменальное количество confu-Сьон. Когда программист видит код, который, кажется, обращается к поле, есть много предположений что программист делает то, что может не быть правдой для собственности. За Например,

  • Свойство может быть доступно только для чтения или только для записи; доступ к полю всегда
    читаемый и доступный для записи. Если вы определите
    собственность, лучше всего предложить как 1015 * получить и установить методы доступа.
  • Метод свойства может вызвать исключение; доступ к полю никогда не выбрасывает
    исключение.

  • Свойство не может быть передано как параметр out или ref параметру Способ; поле может.

  • Метод свойства может занять много времени; доступ к полю всегда
    завершает сразу. Распространенный
    причина использовать свойства
    выполнить синхронизацию потоков, которая может остановить поток навсегда, и
    следовательно, свойство не должно быть
    используется, если синхронизация потока
    требуется. В этой ситуации метод является предпочтительным. Кроме того, если ваш класс может быть доступным удаленно (например,
    ваш класс является производным от
    System.MashalByRefObject), вызов
    метод свойства будет очень
    медленный, и, следовательно, метод
    предпочел недвижимость. По моему
    мнение, классы производные от
    MarshalByRefObject никогда не должен использовать
    свойства.

  • Если вызывается несколько раз подряд, метод свойства может вернуть
    разные значения каждый раз; а
    поле возвращает одно и то же значение каждый
    время. Класс System.DateTime имеет Только для чтения Теперь свойство, которое возвращает
    текущая дата и время. Каждый раз Вы запросите это свойство, оно будет
    вернуть другое значение. Это
    ошибка, и Microsoft желает, чтобы
    они могли бы исправить класс, сделав
    Теперь метод вместо свойства.

  • Метод свойств может вызывать наблюдаемые побочные эффекты; доступ к полю никогда не делает Другими словами, пользователь тип должен иметь возможность устанавливать различные
    свойства, определенные типом в любом
    порядок, который он или она выбирает без
    замечая любое другое поведение в
    тип.

  • Метод свойства может потребовать дополнительной памяти или вернуть
    ссылка на то, что не
    на самом деле часть состояния объекта, поэтому изменение возвращенного объекта имеет
    не влияет на исходный объект;
    запрос поля всегда возвращает
    ссылка на объект
    гарантированно будет частью оригинала состояние объекта. Работа с
    свойство, которое возвращает копию, может быть
    очень запутанно для разработчиков и
    эта характеристика часто не документированы.
0 голосов
/ 10 апреля 2009

Да, get и set популярны в мире c ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...