如何在没有setter的情况下设置类内部类的成员变量?

How to set member variables of class inside class without setter?

本文关键字:内部类 成员 变量 设置 情况下 setter      更新时间:2023-10-16

我想在不使用setters的情况下设置类内部类的成员变量的值。

我的代码:

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;

然后内部ofGLFWWindowSettingsnumSamplesresizable应立即设置为这些值。

是否有任何可能的解决方案可以在不使用二传手或继承ofGLFWWindowSettings的情况下实现这一目标?

是的,有几个选项,与您喜欢的语法具有不同程度的相似性。

选项 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;
};

优点:

  • 正是您想要的语法。

缺点:

  • 非常冗长的定义。很容易错过某个地方的错误。

选项 2 - 公共ofGLFWWindowSettings

class MyWindowSettings {   
public:
ofGLFWWindowSettings settings;
};

优点:

  • 非常简洁
  • 你也不需要吸气剂来ofGLFWWindowSettings

缺点:

  • 语法不完全一样

我个人更喜欢这个,假设MyWindowSettings还有其他成员没有显示。

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

选项 3 - 无MyWindowSettings

只需直接使用ofGLFWWindowSettings

选项 3.a - 别名定义

using MyWindowSettings = ofGLFWWindowSettings;

如果您有权访问类的代码ofGLFWWindowSettings则可以将其成员定义为引用itn numSamplesbool resizable,以便在构造函数中启动。然后MyWindowSettings的构造函数将其成员int numSamplesbool 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::numSamplesofGLFWWindowSettings::resizable只是参考,它们始终是最新的。

如果您在编写settings.numSamples = 8时需要更复杂的行为,例如修改对象ofGLFWWindowSettings settings或调用其他一些成员函数,那么您可以重载operator=。也就是说,您可以将其声明为用户定义的类,而不是将MyWindowSettings::numSamples声明为简单的 int,该类重新定义了其operator=,即采用 int,同时根据需要执行一些其他工作。但在这一点上,我想"二传手"套路会是一个更容易的选择。

是的- 如果你使用Visual Studio编译器。

您可以使用 declspec(property( 设置 numSamples 并可调整大小,您的代码如下所示:

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
}
}