如何制作不可访问的 class 变量
How to make inaccessible class variable
我想知道是否可以在 class 中使 class 变量不可访问?更改此变量值的唯一方法是通过 class setter。例如:
class foo
{
private:
int m_var;
bool m_isBig;
void setVar(int a_var)
{
// do something before setting value, like emitting signal
m_var = a_var;
}
void method()
{
int copy = m_var; // ok
m_var = 5; // error!
setVar(101); // ok
doSomething();
}
void doSomething()
{
if(m_var > 5)
{ m_isBig = true; }
else
{ m_isBig = false; }
}
};
我知道我只能用 setters 和 getter 写另一个 class,但是我将无法从 class foo(封装!)。我认为这可能是一个常见问题,并且可能有一些设计模式,但我找不到。
编辑:
我编辑了代码以明确我想在 setter.
中做什么
您可以将整数包装到特殊的 class 中,并且只定义 setVar()
,而不是采用 int
的赋值运算符
class M_type
{
int m_var;
public:
explicit M_type(int m) : m_var{m} {}
operator int() const { return m_var; }
void setVar(int a_var) { m_var = a_var; }
};
class foo
{
M_type m_var;
bool m_isBig;
public:
explicit foo(int m) : m_var{m} {};
void method()
{
int copy = m_var; // OK, calls operator int()
m_var = 5; // error, no operator=(int)
m_var.setVar(101); // OK, calls setVar(int)
doSomething();
}
void doSomething()
{
if(m_var > 5)
{ m_isBig = true; }
else
{ m_isBig = false; }
}
};
确保给 M_type
一个采用 int
的 explicit
构造函数,并且只有一个充当 "getter" 的隐式转换 operator int()
。如果您也隐式构造函数,编译器生成的赋值 operator=(M_type const&)
将能够将参数 5
转换为 M_type
.
在 C++ 中你不能完全按照你的要求去做。 class 中的所有变量对 class 中的所有方法都是可见的,无论它们是 public 还是私有的。
您想问自己的问题是:为什么 class 想要对自己隐藏一些东西? class 的接口是class 的内部实现和它对外提供的服务之间的边界。您要么在 class 内部,要么在外部。
考虑到这一点,也许您的用例是编写额外的 class 是合适的做法?
我不知道这种模式,但一种可能是将成员包装在嵌套的 class 中。我认为这也是更好的风格,因为创建一个新类型表达了这个成员不仅仅是一个整数的意图,而是具有独特的行为。
class foo {
class MVar {
public:
MVar(foo* parent, int value = 0) : m_parent(parent), m_value(value) {}
MVar& operator=(const MVar&) = delete; // disable assignment
operator int() const { return m_var; }
void set(int new_value) {
// do something, possibly with m_parent
// nested classes have access to the parent's private members
m_value = new_value;
}
private:
foo* m_parent;
int m_value;
} m_var;
void method() {
int copy = m_var; // ok
m_var = 5; // error
MVar.set(101); // ok
}
};
这并不能完全满足您的要求,因为 m_var
确实 没有类型 int
,但这是需要考虑的事情。
我想知道是否可以在 class 中使 class 变量不可访问?更改此变量值的唯一方法是通过 class setter。例如:
class foo
{
private:
int m_var;
bool m_isBig;
void setVar(int a_var)
{
// do something before setting value, like emitting signal
m_var = a_var;
}
void method()
{
int copy = m_var; // ok
m_var = 5; // error!
setVar(101); // ok
doSomething();
}
void doSomething()
{
if(m_var > 5)
{ m_isBig = true; }
else
{ m_isBig = false; }
}
};
我知道我只能用 setters 和 getter 写另一个 class,但是我将无法从 class foo(封装!)。我认为这可能是一个常见问题,并且可能有一些设计模式,但我找不到。
编辑: 我编辑了代码以明确我想在 setter.
中做什么您可以将整数包装到特殊的 class 中,并且只定义 setVar()
,而不是采用 int
class M_type
{
int m_var;
public:
explicit M_type(int m) : m_var{m} {}
operator int() const { return m_var; }
void setVar(int a_var) { m_var = a_var; }
};
class foo
{
M_type m_var;
bool m_isBig;
public:
explicit foo(int m) : m_var{m} {};
void method()
{
int copy = m_var; // OK, calls operator int()
m_var = 5; // error, no operator=(int)
m_var.setVar(101); // OK, calls setVar(int)
doSomething();
}
void doSomething()
{
if(m_var > 5)
{ m_isBig = true; }
else
{ m_isBig = false; }
}
};
确保给 M_type
一个采用 int
的 explicit
构造函数,并且只有一个充当 "getter" 的隐式转换 operator int()
。如果您也隐式构造函数,编译器生成的赋值 operator=(M_type const&)
将能够将参数 5
转换为 M_type
.
在 C++ 中你不能完全按照你的要求去做。 class 中的所有变量对 class 中的所有方法都是可见的,无论它们是 public 还是私有的。
您想问自己的问题是:为什么 class 想要对自己隐藏一些东西? class 的接口是class 的内部实现和它对外提供的服务之间的边界。您要么在 class 内部,要么在外部。
考虑到这一点,也许您的用例是编写额外的 class 是合适的做法?
我不知道这种模式,但一种可能是将成员包装在嵌套的 class 中。我认为这也是更好的风格,因为创建一个新类型表达了这个成员不仅仅是一个整数的意图,而是具有独特的行为。
class foo {
class MVar {
public:
MVar(foo* parent, int value = 0) : m_parent(parent), m_value(value) {}
MVar& operator=(const MVar&) = delete; // disable assignment
operator int() const { return m_var; }
void set(int new_value) {
// do something, possibly with m_parent
// nested classes have access to the parent's private members
m_value = new_value;
}
private:
foo* m_parent;
int m_value;
} m_var;
void method() {
int copy = m_var; // ok
m_var = 5; // error
MVar.set(101); // ok
}
};
这并不能完全满足您的要求,因为 m_var
确实 没有类型 int
,但这是需要考虑的事情。