Реализуйте значение по умолчанию в C ++ - PullRequest
1 голос
/ 19 декабря 2011

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

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

Таким образом, я думаю, что у меня есть два метода:

  • Использовать указатели: если указатель равен nullptr, тогда использовать родительское значение.
  • Используйте поле bool для каждого атрибута, указывая статус.

Оба метода должны работать, но они также имеют неудобства:

  • Для первого потребуется создание экземпляра вручную, даже если его можно упростить с помощью shared_ptr или unique_ptr. Но это приведет к дополнительным инструкциям, таким образом, более медленный код
  • Второе приведет к дополнительному потреблению памяти: каждый экземпляр будет занимать как минимум еще один байт (чаще всего 2, 4 или даже 8 байт) на каждый атрибут.

Мой вопрос: Есть ли другой способ реализовать такое поведение? Или какое лучшее решение?

Ответы [ 2 ]

2 голосов
/ 19 декабря 2011

Второе приведет к дополнительному потреблению памяти: каждый экземпляр займет как минимум еще один байт (чаще всего 2, 4 или даже 8 байт) за атрибут.

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

1 голос
/ 19 декабря 2011

Может быть использован следующий базовый строительный блок: Ссылка по умолчанию:

#include <memory>
#include <utility>

template <typename T>
struct RefWithDefault
{
    /* external reference version */
    RefWithDefault(T & x) : r(x) { }

    /* default-initialize version */
    RefWithDefault() : p(new T), r(*p) { }

    /* value/direct-initialize version */
    template <typename ...Args> 
    RefWithDefault(Args &&... args) : p(new T(std::forward<Args>(args)...)), r(*p) { }

    T & operator() { return r; }

private:
    std::unique_ptr<T> p;
    T & r;
};

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

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