Хорошо ли, чтобы все функции setter возвращали ссылку на объект в C++?Хорошо ли, чтобы все функции setter возвращали ссылку на объект в C++?
ответ
Это достаточно удобный образ, если есть много вещей, которые необходимо установить на объекте.
class Foo
{
int x, y, z;
public:
Foo &SetX(int x_) { x = x_; return *this; }
Foo &SetY(int y_) { y = y_; return *this; }
Foo &SetZ(int z_) { z = z_; return *this; }
};
int main()
{
Foo foo;
foo.SetX(1).SetY(2).SetZ(3);
}
Эта модель заменяет конструктор, который принимает три Интс:
int main()
{
Foo foo(1, 2, 3); // Less self-explanatory than the above version.
}
Это полезно, если у вас есть несколько значений, которые не всегда должны быть установлены.
Для справки, более полный пример такого рода техники называется «Named Parameter Idiom» в C++ FAQ Lite.
Конечно, если вы используете это для именованных параметров, вы можете взглянуть на boost::parameter. Или вы не можете ...
Я бы так не подумал. Как правило, вы думаете об объекте «setter», как только это.
Кроме того, если вы только что установили объект, у вас нет указателя на него?
Не все сеттеры, но некоторые из них могут возвращать ссылку на объект, который будет полезен.
вид
a.SetValues(object)(2)(3)(5)("Hello")(1.4);
Я использовал этот раз давно построить SQL построитель выражений, который обрабатывает все проблемы ускользает и другие вещи.
SqlBuilder builder;
builder.select(column1)(column2)(column3).
where("=")(column1, value1)
(column2, value2).
where(">")(column3, 100).
from(table1)("table2")("table3");
Я не смог воспроизвести источники за 10 минут. Таким образом, реализация за шторами.
Я сделал аналогичный материал для создания XML-документов на C++. Вопрос здесь, однако, кажется, касается общих свойств. –
Вы можете вернуть ссылку на this
, если вы хотите, чтобы функция цепи сеттер вызовы вместе, как это:
obj.SetCount(10).SetName("Bob").SetColor(0x223344).SetWidth(35);
Лично я считаю, что код труднее читать, чем альтернатива:
obj.SetCount(10);
obj.SetName("Bob");
obj.SetColor(0x223344);
obj.SetWidth(35);
Речь идет о макете. Вы можете просто написать первую часть, как вторую, просто опуская obj. на все, кроме первого и; на все, кроме последнего. ИМХО, это так же читаемо. –
Если ваша мотивация связана с цепочкой (например, предложение Брайана Энсинка), я бы предложил два комментария:
1. Если вы обнаружите, что часто настраиваете многие вещи одновременно, это может означать, что вы должны создать struct
или class
, который содержит все эти настройки, чтобы все они могли быть переданы сразу. Следующим шагом может быть использование этого или class
в самом объекте ... но поскольку вы используете геттеры и сеттеры, решение о том, как его представлять внутри, будет всегда прозрачным для пользователей этого класса, поэтому это решение будет больше относятся к тому, насколько сложным является класс, чем что-либо.
2. Одна из альтернатив сеттера - это создание нового объекта, его изменение и его возврат. Это неэффективно и неприемлемо для большинства типов, особенно для изменяемых типов. Однако это вариант, который иногда забывают люди, несмотря на то, что он используется в классе строк многих языков.
Этот метод используется в Named parameter Idiom.
Типичная цель этого стиля используется для построения объекта.
Person* pPerson = &(new Person())->setAge(34).setId(55).setName("Jack");
вместо
Person* pPerson = new Person(34, 55, "Jack");
Использование второй более традиционный стиль можно было бы забыть, если первое значение, передаваемое в конструктор был возраст или идентификатор? Это может также привести к созданию нескольких конструкторов, основанных на справедливости некоторых свойств.
Использование первого стиля позволяет забыть установить некоторые свойства объекта и может привести к ошибкам, когда объекты не «полностью» построены. (Свойство класса добавлено в более поздний момент, но не все места строительства были обновлены, чтобы вызвать требуемый сеттер.)
Поскольку код развивается, мне очень нравится, что я могу использовать компилятор, чтобы помочь мне найти все места где объект создается при изменении подписи конструктора. Поэтому по этой причине я предпочитаю использовать обычные конструкторы C++ для этого стиля.
Эта модель может хорошо работать в приложениях, которые поддерживают их DataModel с течением времени в соответствии с правилами, аналогичных тем, которые используются во многих приложениях баз данных:
- Вы можете добавить поле/атрибут таблицы/класс, который является NULL по умолчанию. (Таким образом, для обновления существующих данных требуется только новый столбец NULL в базе данных.)
- Код, который не является изменением, должен по-прежнему работать так же, как и в этом поле NULL.
+1 для безопасности во время компиляции. – Eclipse
Ничего себе. Это потрясающая адаптация к отсутствию названных параметров C++ (например, Ada уже 20 лет). –
-> нет. для указателей, хотя :) –
IMO сеттеры код запах, который обычно указывают на один из двух вещей:
Making A Mountian из кротовой норы
Если у вас есть класс вроде этого:
class Gizmo
{
public:
void setA(int a) { a_ = a; }
int getA() const { return a_; }
void setB(const std::string & b) { v_ = b; }
std::string getB() const { return b_; }
private:
std::string b_;
int a_;
};
... и значения действительно такие простые, то почему бы не просто сделать пользователей данных общедоступными ?:
class Gizmo
{
public:
std::string b_;
int a_;
};
... Гораздо проще и, , если данные, которые просто вы ничего не теряете.
Другая возможность заключается в том, что вы могли бы быть
Изготовление кротовой норы из Mountian
Много раз данные не так просто: может быть, вы должны изменить несколько значений, сделать некоторые вычисления, уведомлять о другом объекте; кто знает что. Но если данные нетривиальны, то вам действительно нужны сборщики & геттеров, тогда нетривиальных достаточно для обработки ошибок. Таким образом, в этих случаях ваши приемники & должны возвращать какой-то код ошибки или делать что-то еще, чтобы указать, что произошло что-то плохое.
Если вы цепочки вызовов вместе, как это:
A.doA().doB().doC();
... и DOA() терпит неудачу, вы действительно хотите, чтобы называть DOB() и РОУ() в любом случае? Я сомневаюсь в этом.
RE: "A.doA(). DoB(). DoC();" если doA терпит неудачу, для этого есть исключения. – Eclipse
+1, хороший момент Джон. Также хороший момент Джош. –
- 1. Возможно ли, чтобы get_posts() или WP_Query не возвращали содержимое сообщения?
- 2. Возможно ли, чтобы SelectNodes на XmlDocument возвращали значение null?
- 3. Сохранять ссылку на объект в рекурсивной функции
- 4. Хорошо ли возвращать вызов функции?
- 5. C# непреложный объект setter понимание
- 6. Хорошо, что «все есть объект»?
- 7. Как я могу сделать, чтобы метки возвращали значения в C#?
- 8. Есть ли способ передать ссылку на объект?
- 9. Хорошо, чтобы создать объект в представлении?
- 10. Сохранять объект и ссылку на объект, созданный внутри функции
- 11. C++, передающий ссылку на объект const для функции
- 12. Как создать ссылку на объект в C#?
- 13. Как передать ссылку на объект через функции?
- 14. Как передать ссылку на объект анонимной функции?
- 15. Получить ссылку на объект и имя функции
- 16. C#: преобразовать строку в ссылку на объект
- 17. Как управлять ссылку на объект в C#
- 18. C# - Сохраняет ли листинг ссылку на исходный объект?
- 19. В C# хорошо ли использовать рекурсивные функции в алгоритмах?
- 20. В C++ 11 есть ли еще необходимость передать ссылку на объект, который будет принимать вывод функции?
- 21. Возвращая ссылку на объект
- 22. Листинг объекта в C# всегда возвращает ссылку на исходный объект
- 23. Преобразование строки в ссылку на объект?
- 24. C# SQLite объект пользовательский getter и setter
- 25. C++/CLI: вернуть ссылку на неуправляемый объект
- 26. Хорошо для ivar хранить ссылку на владельца?
- 27. Преобразование строки в точечную нотацию, чтобы получить ссылку на объект
- 28. Получить ссылку на объект из C# выражения
- 29. функции C++ сделать ссылку
- 30. Как передать ссылку C# на COM-объект на C++ DLL
Я заинтригован этой техникой в последнее время. Будет интересно посмотреть, есть ли у кого-нибудь какие-либо недостатки. –
Интересно. Я не считал это альтернативой сложным конструкторам. Этот метод может сократить большое количество перегрузок конструктора. –
Есть некоторые вещи, которые вы не можете сделать с этим, что вы можете делать с конструкторами (например, инициализация констант и ссылок). – Eclipse