В C # есть хороший синтаксический сахар для полей с геттером и сеттером. Кроме того, мне нравятся автоматически реализованные свойства, которые позволяют мне писать
public Foo foo { get; private set; }
На C ++ мне нужно написать
private:
Foo foo;
public:
Foo getFoo() { return foo; }
Есть ли такая концепция в C ++ 11, позволяющая мне добавить немного синтаксического сахара к этому?
Ответы:
В C ++ вы можете писать свои собственные функции. Вот пример реализации свойств с использованием безымянных классов. Статья в Википедии
Вы можете написать свои собственные геттеры и сеттеры на месте, и если вам нужен доступ к члену класса-держателя, вы можете расширить этот пример кода.
источник
_alpha
для частной переменной иalpha
для справки.sizeof(Foo)
.В C ++ этого нет, вы можете определить шаблон для имитации функциональности свойств:
Чтобы определить свойство :
Чтобы реализовать собственный метод получения / установки, просто наследовать:
Чтобы определить свойство только для чтения :
И использовать это в классе
Owner
:Вы можете определить некоторые из вышеперечисленных макросов, чтобы сделать его более кратким.
источник
virtual
это , вероятно , нет необходимости для большинства случаев использования, так как недвижимость вряд ли будут использовать полиморфно.В языке C ++ нет ничего, что могло бы работать на всех платформах и компиляторах.
Но если вы хотите нарушить кросс-платформенную совместимость и выполнить привязку к конкретному компилятору, вы можете использовать такой синтаксис, например, в Microsoft Visual C ++, вы можете сделать
источник
Вы можете до некоторой степени эмулировать геттер и сеттер, имея член выделенного типа и переопределяя
operator(type)
иoperator=
для него. Хорошая ли это идея - другой вопрос, и я собираюсь+1
ответить Керреку С.Б., чтобы высказать свое мнение по этому поводу :)источник
friend
к владельцу поля.Может быть, взгляните на класс свойств, который я собрал за последние часы: /codereview/7786/c11-feedback-on-my-approach-to-c-like-class-properties
Это позволяет вам вести себя следующим образом:
источник
В C ++ 11 вы можете определить шаблон класса Property и использовать его следующим образом:
А вот и шаблон класса Property.
источник
C::*
значит? Я никогда раньше не видел ничего подобного?C
. Это похоже на простой указатель на функцию, но для вызова функции-члена вам необходимо предоставить объект, для которого функция вызывается. Это достигается с помощью строкиitsObject->*itsSetter(theValue)
в примере выше. См. Здесь более подробное описание этой функции.Как уже говорили многие, в языке нет встроенной поддержки. Однако, если вы ориентируетесь на компилятор Microsoft C ++, вы можете воспользоваться специфическим для Microsoft расширением свойств, которое задокументировано здесь.
Это пример со связанной страницы:
источник
Нет, в C ++ нет понятия свойств. Хотя может быть неудобно определять и вызывать getThis () или setThat (value), вы делаете заявление потребителю этих методов, что некоторые функции могут возникнуть. С другой стороны, доступ к полям в C ++ сообщает потребителю, что никаких дополнительных или неожиданных функций не произойдет. Свойства сделали бы это менее очевидным, поскольку доступ к свойствам на первый взгляд кажется реагирующим как поле, но на самом деле реагирует как метод.
Кстати, я работал над .NET-приложением (очень известной CMS), пытаясь создать систему членства клиентов. Из-за того, как они использовали свойства своих пользовательских объектов, срабатывали действия, которых я не ожидал, в результате чего мои реализации выполнялись причудливыми способами, включая бесконечную рекурсию. Это было связано с тем, что их пользовательские объекты обращались к уровню доступа к данным или какой-либо глобальной системе кэширования при попытке доступа к таким простым вещам, как StreetAddress. Вся их система была основана на том, что я бы назвал злоупотреблением собственностью. Если бы они использовали методы вместо свойств, думаю, я бы гораздо быстрее понял, что пошло не так. Если бы они использовали поля (или, по крайней мере, сделали бы их свойства более похожими на поля), я думаю, что систему было бы легче расширять и поддерживать.
[Edit] Изменил свои мысли. У меня был плохой день, и я немного рассердился. Эта очистка должна быть более профессиональной.
источник
На основе https://stackoverflow.com/a/23109533/404734 вот версия с публичным получателем и частным сеттером:
источник
Это не совсем свойство, но оно делает то, что вы хотите, простым способом:
Здесь большой X ведет себя как
public int X { get; private set; }
в синтаксисе C #. Если вам нужны полноценные свойства, я сделал первую попытку реализовать их здесь .источник
X
на новый объект по-прежнему будет указывать на член старого объекта, потому что он просто копируется как член-указатель. Это плохо само по себе, но когда старый объект удаляется, поверх него появляется повреждение памяти. Чтобы это работало, вам также нужно будет реализовать собственный конструктор копирования, оператор присваивания и конструктор перемещения.Вы, наверное, это знаете, но я бы просто сделал следующее:
Этот подход прост, не требует никаких хитростей и выполняет свою работу!
Проблема, однако, в том, что некоторым людям не нравится ставить перед своими частными полями знак подчеркивания, и поэтому они не могут использовать этот подход, но, к счастью для тех, кто это делает, это действительно просто. :)
Префиксы get и set не добавляют ясности вашему API, но делают их более подробными, и причина, по которой я не думаю, что они добавляют полезную информацию, заключается в том, что когда кому-то нужно использовать API, если API имеет смысл, он, вероятно, поймет, что это обходится без префиксов.
Еще одна вещь: легко понять, что это свойства, потому что
name
это не глагол.В худшем случае, если API-интерфейсы согласованы и человек не осознает, что
name()
это аксессор иname(value)
мутатор, ему нужно будет только один раз просмотреть его в документации, чтобы понять шаблон.Насколько я люблю C #, я не думаю, что C ++ вообще нуждается в свойствах!
источник
foo(bar)
(вместо более медленныхfoo = bar
), но ваши аксессоры вообще не имеют ничего общего со свойствами ...foo(bar)
аfoo=bar
не с помощьюvoid foo(Bar bar)
метода мутатора для_foo
переменной-члена.Нет ... Но вы должны подумать, если это просто функция get: set и никакие дополнительные задачи не выполняются внутри методов get: set, просто сделайте ее общедоступной.
источник
Я собрал идеи из нескольких источников C ++ и поместил их в красивый, все еще довольно простой пример для геттеров / сеттеров на C ++:
Вывод:
Вы можете протестировать его онлайн здесь: http://codepad.org/zosxqjTX
источник
Действительно ли вашему классу нужно применять какой-то инвариант или это просто логическая группировка элементов-членов? Если это последнее, вам следует подумать о том, чтобы создать структуру и получить прямой доступ к членам.
источник
Есть набор макросов , написанных здесь . В нем есть удобные объявления свойств для типов значений, ссылочных типов, типов только для чтения, сильных и слабых типов.
источник