2015-09-26 4 views
3

A. Насколько полезной или громоздкой является следующая методика использования той же функции как для геттера, так и для сеттера путем возврата ссылки?Опорный возврат для сеттера

B. Насколько хороша практика добавления константы в конце описаний функций в случае геттеров и сеттеров?

#include <iostream> 

class A 
{ 
    int varReadWrite_; 
    int varReadOnly_; 
    int varRestricted_; 

public: 
    A() : varReadOnly_(25) {} 
    virtual ~A() {} 

    int& varReadWrite() { return varReadWrite_; } 
    int varReadOnly() { return varReadOnly_; } 
    int varRestricted() { return varRestricted_; } 
    void setVarRestricted(int i); //throwable 

}; 

int main(int argc, char *argv[]) 
{ 
    A a; 
    a.varReadWrite() = 45; 
    std::cout << a.varReadOnly() << a.varReadWrite() << std::endl; 
    return 0; 
} 

Причина, почему я выбрал именно этот проект был:

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

Использование boost fusion map также интересную возможность, как shown here

Update

Const Ссылка Пользователи интересны только для чтения доступ к переменным, например,

class A { 
    int mA; 
public: 
    int& a; 
    A(int a_ = 0) : mA(a_), a(mA) {} 
}; 

Практически это происходит с дополнительным усилием в коде копировать и перемещать конструкторы, что является приемлемым компромиссом для меня.

Cpp Reference Copy Construtor says

неявно объявленный или дефолт конструктор копирования для класса Т определяются как удаляется, если ... T имеет не-статические элементы данных, которые не могут быть скопированы (удалили, недоступный , или неоднозначные конструкторы копирования);

+4

Это так же хорошо или громоздко, как использование переменной открытого элемента. –

+2

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

+1

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

ответ

3

A. Насколько полезной/громоздкой является следующая попытка использовать ту же функцию для геттера, а также сеттера, возвращая ссылку?

Возвращение ссылки на ваши внутренние член в общем не рекомендуется поскольку таким образом вы даете легкий доступ к другим, чтобы они могли изменить объект внутреннего состояние без использования каких-либо методов, предоставляемого класс API объекта. Таким образом, будет очень сложно отслеживать такие изменения в коде. В общем случае изменения внутреннего состояния объекта должны быть возможны только с помощью методов, принадлежащих API класса.

B. Насколько хороша практика добавления константы в конце объявлений функций в случае геттеров и сеттеров?

, если вы обратитесь к добавлению сопзИте методы, такие как:

void PrintState() const 

Тогда в общем случае это не имеет смысла для сеттеров. Константа в этом случае означает Этот метод не изменяет состояние объекта. Итак, это обязательство, которое вы даете вызывающему, чтобы сказать: Я не изменю объект состояние этим звонком. В целом, это очень хорошая практика, так как она помогает вам во время разработки думать о ваших методах и видеть, какая из них действительно изменяет состояние объекта или нет. Кроме того, это защитное программирование с , это рекурсивное: если вы передаете этот объект некоторому методу по ссылке (через указатель или ссылку), он не может вызывать методы const, если этот метод не помечен как const. Таким образом, это предотвращает изменение состояния объекта по ошибке.

+0

Спасибо за описательный ответ. Это дает мне представление о том, как я должен подходить к конкретным задачам программирования. Я еще не могу говорить о разработке программного обеспечения, но я уверен, что это у меня в голове, когда я там. –

2

Аксессоры (a.k.a get Ters и set Ters), как хорошо/громоздким как имеющие переменные открытый член, а you've just violated encapsulation and lied yourself. Смешение их в одной функции еще хуже, так как вызывающий может удерживать возвращенную ссылку, открывая отверстие для еще более тонких ошибок, чем описано в ссылке выше.

Во-вторых, добавление const к объявлению функции участника защитит вас от set ters, но не от get ters. В любом случае, лучше планируйте свои проекты :).

+0

Спасибо за ссылку. Это было проницательно. Я не мог понять изменения дизайна, предложенные для простых старых структур. А также о том, что считается плохой/опасной/грязной об их использовании в мета-программировании шаблонов. Можно ли спросить здесь или открыть новый поток. –

+1

@bvraghav: Здесь все в порядке, потому что это примерно один из моих предыдущих ответов. То, что я пытался сказать о POS (Plain-Old-Structs), заключается в том, что они должны использоваться в двух случаях. Прежде всего, когда их единственная цель - хранить простые данные (без прямого кода), характерные для единицы перевода (файл a.k.a '.cpp'). Второе использование исходит из того, когда вы попадаете в метапрограммирование шаблонов, где они просто бесценный камень с точки зрения дизайна. ** ПРОДОЛЖЕНИЕ **. – 3442

+1

@bvraghav: ** ПРОДОЛЖЕНИЕ **. Дело в том, что (в большинстве случаев), когда они используются в метапрограммировании шаблонов, они не содержат данных вообще, ни связанного кода, потому что нет связанных данных. Обычно они содержат такие вещи: typedef или 'constexpr size_t'. В этом случае использование 'class'es просто глупо, потому что инкапсулировать вообще нечего. Прокомментируйте здесь, если у вас есть другие сомнения, связанные с ссылкой :). – 3442

Смежные вопросы