Вопрос

Несколько вопросов о методах аксессуаров в C ++ были заданы так, но никто не смог удовлетворить мое любопытство по этому вопросу.

Я стараюсь избегать аксессуаров, когда это возможно, потому что, подобно Stroustrup и других известных программистов, я считаю классом со многими из них признаком плохого oO. В C ++ я могу в большинстве случаев добавить больше ответственности за класс или использовать ключевое слово «Друг», чтобы избежать их. Тем не менее, в некоторых случаях вам действительно нужен доступ к конкретным классам.

Есть несколько возможностей:

1. Не используйте аксессуары вообще

Мы можем просто сделать соответствующие переменные участника публику. Это нехорошо в Java, но, похоже, в порядке с сообществом C ++. Тем не менее, я немного беспокоюсь о случаях, были явная копия или ссылка только для чтения (Const) на объект, если это преувеличено?

2. Используйте методы Get / Set в стиле Java

Я не уверен, что это вообще от Java, но я имею в виду это:

int getAmount(); // Returns the amount
void setAmount(int amount); // Sets the amount

3. Используйте объективные методы Get / Sette / Set

Это немного странно, но, видимо, все более распространено:

int amount(); // Returns the amount
void amount(int amount); // Sets the amount

Для того, чтобы начать работу, вам придется найти другое имя для вашей переменной элемента. Некоторые люди добавляют подчеркивание, другие предложены «M_». Я тоже не люблю.

Какой стиль вы используете и почему?

Это было полезно?

Решение

С моей точки зрения, как сидение с 4 миллионами линий кода C ++ (и это просто один проект) с точки зрения обслуживания, я бы сказал:

  • Это нормально, чтобы не использовать GetTers / Setters, если члены неизмерены (то есть const) или просто без зависимостей (как класс точки с членами x и y).

  • Если член есть private Только это также нормально, чтобы пропустить GetTers / Getters. Я также считаю членов внутренних пропитыватьОбласти как private Если блок .CPP невелик.

  • Если член есть public или protected (protected так же плохо, как public) и неconst, непростые или имеют зависимости, затем используют GetTers / Deventers.

В качестве обслуживания парень моя главная причина желающих иметь GetTers / Setters, заключается в том, что тогда у меня есть место, чтобы поставить точки перерыва / регистрацию / что-то еще.

Я предпочитаю стиль альтернативы 2. Как это более доступно (ключевой компонент в письменном виде).

Другие советы

2) - лучший IMO, потому что это делает ваши намерения ясными. set_amount(10) более значимо, чем amount(10), и как хороший побочный эффект позволяет члену названо amount.

Общественные переменные есть как правило Плохая идея, потому что нет никакой инкапсуляции. Предположим, вам нужно обновить кеш или обновить окно, когда переменная обновляется? Жаль, если ваши переменные являются публичными. Если у вас есть набор метод, вы можете добавить его там.

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

    Конечно, в реальности inline явные Getter или Getters создают столько же базовой зависимости от реализации класса. Они просто уменьшают семантическую зависимость. Вы все еще должны перекомпилировать все, если вы их измените.

  2. Это мой стиль по умолчанию, когда я использую методы доступа.

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

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

  1. Это хороший стиль, если мы просто хотим представлять pure данные.

  2. Мне это не нравится :) потому что get_/set_ действительно не нужно, когда мы можем перегружать их в C ++.

  3. STL использует этот стиль, такой как std::streamString::str а также std::ios_base::flags, За исключением случаев, когда следует избегать! когда? Когда имя метода конфликтует с именем другого типа, то get_/set_ стиль используется, например std::string::get_allocator потому что std::allocator.

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

Сказав это, если такой дизайн должен быть повторной рефраксированной, и исходный код доступен, я бы предпочел использовать шаблон дизайна посетителей. Причина в том:

. Это дает класс возможность решить, кому разрешить доступ к своему частным государстве

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

с. Это четко документирует такой эктера доступа через интерфейс четкого класса

Основная идея:

а) редизайн, если это возможно,

б) рефакторист так, что

  1. Весь доход к классу состояния находится через хорошо известное индивидуалистическийинтерфейс

  2. Должно быть возможно настроить некоторые из них и не делать для каждого такого интерфейса, например, весь доступ от внешнего объекта ХОРОШОДолжен быть допущен, все доступ от внешнего объекта ПЛОХОЙ должно быть запрещено, а внешнее сущность OkДолжно быть разрешено получить но не установить (например)

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

  2. Это не имеет значения, не имеет значение в соответствии с Конвенцией именования, если вы согласуетесь в вашем коде. Если вы используете несколько сторонних библиотек, они могут воспользоваться различными конвенциями именования. Так что дело в вкусе.

Я видел идеализацию классов вместо интегральных типов для обозначения значимых данных.

Что-то вроде этого ниже, как правило, не хорошо пользуется свойствами C ++:

struct particle {
    float mass;
    float acceleration;
    float velocity;
} p;

Почему? Потому что результат p.mass * p.Acceleration - это поплавок и не заставляют, как ожидалось.

Определение классов для обозначения цели (даже если это значение, как количество упоминается ранее) имеет больше смысла и позволит нам сделать что-то вроде:

struct amount
{
    int value;

    amount() : value( 0 ) {}
    amount( int value0 ) : value( value0 ) {}
    operator int()& { return value; }
    operator int()const& { return value; }
    amount& operator = ( int const newvalue )
    {
        value = newvalue;
        return *this;
    }
};

Вы можете получить доступ к значению в количестве неявно с помощью оператора INT. Более того:

struct wage
{
    amount balance;

    operator amount()& { return balance; }
    operator amount()const& { return balance; }
    wage& operator = ( amount const&  newbalance )
    {
        balance = newbalance;
        return *this;
    }
};

Использование Getter / Setter:

void wage_test()
{
    wage worker;
    (amount&)worker = 100; // if you like this, can remove = operator
    worker = amount(105);  // an alternative if the first one is too weird
    int value = (amount)worker; // getting amount is more clear
}

Это другой подход, не означает, что это хорошо или плохо, но другой.

Позвольте мне рассказать вам о одной дополнительной возможности, которая кажется самым дизайном.

Нужно прочитать и модифицировать

Просто объявляйте эту переменную публику:

class Worker {
public:
    int wage = 5000;
}

worker.wage = 8000;
cout << worker.wage << endl;

Нужно просто читать

class Worker {
    int _wage = 5000;
public:
    inline int wage() {
        return _wage;
    }
}

worker.wage = 8000; // error !!
cout << worker.wage() << endl;

Недостатком этого подхода является то, что вам нужно изменить весь код вызова (Добавить скобки, то есть), когда вы хотите изменить шаблон доступа.

Дополнительная возможность может быть:

int& amount();

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

str.length() = 5; // Ok string is a very bad example :)

Иногда это, может быть, просто хороший выбор, чтобы сделать:

image(point) = 255;  

Еще одна возможность, используйте функциональную запись для изменения объекта.

edit::change_amount(obj, val)

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top