Как установить переменные-члены класса внутри класса без сеттера? - PullRequest
0 голосов
/ 03 июля 2018

Я бы хотел установить значения переменных-членов класса внутри класса без использования установщиков.

Мой код:

class MyWindowSettings {

public:

    const ofGLFWWindowSettings& get(){
        return settings;
    }
    int numSamples;
    bool resizable;

private:
    ofGLFWWindowSettings settings;
};

ofGLFWWindowSettings также имеет открытые переменные-члены, которые

int numSamples;
bool resizable;

И я хотел бы иметь возможность устанавливать значения этих переменных без использования установщиков.

Я бы хотел иметь возможность ... например,

MyWindowSettings settings;
settings.numSamples = 8;
settings.resizable = true;

Тогда внутренние ofGLFWWindowSettings s numSamples и resizable должны быть немедленно установлены на эти значения.

Есть ли какое-либо возможное решение для достижения этой цели без использования установщиков или наследования ofGLFWWindowSettings?

Ответы [ 3 ]

0 голосов
/ 03 июля 2018

Если у вас есть доступ к коду класса ofGLFWWindowSettings, существует возможность определить его члены itn numSamples и bool resizable в качестве ссылок, которые будут инициализированы в конструкторе. Затем конструктор MyWindowSettings передает свои элементы int numSamples, bool resizable (после инициализации) конструктору ofGLFWWindowSettings.

См. Следующий пример:

struct ofGLFWWindowSettings {
    int& numSamples;
    bool& resizable;

    ofGLFWWindowSettings(int& _numSamples, bool& _resizable) :
                numSamples(_numSamples), resizable(_resizable) { }
};

class MyWindowSettings {

public:

    const ofGLFWWindowSettings& get(){
        return settings;
    }
    int numSamples;
    bool resizable;



  MyWindowSettings(int _numSamples, bool _resizable) :
          numSamples(_numSamples), resizable(_resizable),
          settings(numSamples, resizable) { }


private:
    ofGLFWWindowSettings settings;
};

Будучи ofGLFWWindowSettings::numSamples и ofGLFWWindowSettings::resizable просто ссылками, они всегда актуальны.

Если вам вместо этого требуется более сложное поведение при написании settings.numSamples = 8, например, изменение объекта ofGLFWWindowSettings settings или вызов какой-либо другой функции-члена, тогда вы можете перегрузить operator=. То есть вместо объявления MyWindowSettings::numSamples как простого int вы можете объявить его как определяемый пользователем класс, который переопределяет его operator=, чтобы принимать int и, в то же время, выполнять другую работу, если это необходимо. , Но на данный момент, я предполагаю, что процедура «сеттера» будет более легким выбором.

0 голосов
/ 03 июля 2018

ДА - если вы используете компилятор Visual Studio.

Вы можете установить numSamples и изменить размер, используя declspec (свойство) , ваш код будет выглядеть так:

class MyWindowSettings
{
public:
__declspec( property( put=SetSamples ) ) int numSamples;
__declspec( property( put=SetResizable ) ) bool resizable;

private:
    void SetSamples(int s)
    {
        numSamples = s;
        UpdateOfgl();
    }
    void SetResizable(bool b)
    {
        resizable = b;
        UpdateOfgl();
    }

    void UpdateOfgl()
    {
        //update ofgl settings internal state
    }
}
0 голосов
/ 03 июля 2018

Да, есть несколько вариантов, с различной степенью сходства с синтаксисом, который вы предпочитаете.

Вариант 1 - ссылки на участников

class MyWindowSettings {

public:
    MyWindowSettings()
      : numSamples(settings.numSamples),
        resizable(settings.resizable)
    {}

    ~MyWindowSettings() = default;

    MyWindowSettings(const MyWindowSettings & other)
      : settings(other.settings),
        numSamples(settings.numSamples),
        resizable(settings.resizable)
    {}

    MyWindowSettings& operator=(const MyWindowSettings & other)
    {
        settings = other.settings;
        return *this;
    }

    MyWindowSettings(MyWindowSettings && other)
      : settings(std::move(other.settings)),
        numSamples(settings.numSamples),
        resizable(settings.resizable)
    {}

    MyWindowSettings& operator=(MyWindowSettings && other)
    {
        settings = std::move(other.settings);
        return *this;
    }

    const ofGLFWWindowSettings& get(){
        return settings;
    }
    int & numSamples;
    bool & resizable;

private:
    ofGLFWWindowSettings settings;
};

Pro:

  • Именно тот синтаксис, который вы хотите.

Con:

  • Очень подробное определение. Легко пропустить ошибку где-то там.

Вариант 2 - общедоступный ofGLFWWindowSettings

class MyWindowSettings {   
public:
    ofGLFWWindowSettings settings;
};

Pro:

  • Очень лаконично
  • Вам не нужен геттер для ofGLFWWindowSettings тоже

Con:

  • Не совсем такой же синтаксис

Лично я предпочитаю это, при условии, что есть другие члены MyWindowSettings, которые не показаны.

MyWindowSettings settings;
settings.settings.numSamples = 8;
settings.settings.resizable = true;

Вариант 3 - Нет MyWindowSettings

Просто используйте ofGLFWWindowSettings напрямую вместо

Вариант 3.a - определение псевдонима

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