C++有没有办法创建'super private'变量?
Is there a way in C++ to create 'super private' variables?
我有一个关于c++特性的想法,我想知道是否有可能创建。
假设我希望MyClass中的私有变量只能被两个函数访问,即公共getter和setter。也就是说,如果MyClass的另一个公共或私有函数试图获取或更改我的超私有变量的值,我将得到一个编译错误。但是,getter和setter的行为正常。
任何想法?
编辑1:用例是让getter/setter执行错误检查或其他形式的逻辑。我甚至不希望类本身直接接触变量。
编辑2:然后像这样:
template <class T>
class State{
private:
T state;
public:
State()
{
state = 0;
}
T getState()
{
return state;
}
void setState(T state)
{
this->state = state;
}
};
然后任何类都可以继承它,并且只能通过getter/setter访问'state'。当然,如果不根据所需的逻辑修改getter和setter,这个类是无用的。
在c++中可访问性的粒度是类。
因此,如果你需要使一个变量只能被两个方法访问,你需要将变量和两个方法移动到一个单独的类中,专门用于维护隐私。
您可以将变量包装在一个类中,并在那里使其为私有和const T&
getter。然后将包含类的get和set成员函数声明为该包装器的友元。现在将包装器类保留为原始类的成员。这应该达到你想要的,尽管它看起来很难维护,不是很有用。
所以这里有一些虚拟的实现,展示了它是如何工作的(注意,整个new VeryPrivateWrapper
业务只是一种古怪的声明方式,unique_ptr
将更有帮助):
class VeryPrivateWrapper;
class Original {
VeryPrivateWrapper* m_wrapper;
public:
Original();
// imagine that I remembered the rule of three here
void set(int);
void other();
};
// make this a template for more fun
class VeryPrivateWrapper {
int m;
public:
const int& get() const { return m; }
// !!!
// the important bit
// !!!
friend void Original::set(int);
};
Original::Original() : m_wrapper(new VeryPrivateWrapper) {}
void Original::set(int i) {
m_wrapper->m = i;
}
void Original::other() {
// this borks as we would like
// m_wrapper->m = 23;
}
int main()
{
Original o;
o.set(3);
return 0;
}
我相信这就是你想要的。这是可取的吗?有些人会认为这是令人厌恶的。
如果您决定使用它,您可能需要从宏中取出公共Get和Set,并手动编写它们。
#define SUPER_PRIVATE(c,t,m)
template <typename C, typename T>
class SuperPrivate##m {
friend T& C::Get##m();
friend void C::Set##m(const T&);
T value;
};
public:
t& Get##m() { return m.value; }
void Set##m(const t& value) { m.value = value; }
private:
SuperPrivate##m<c,t> m;
class SomeClass
{
public:
SomeClass()
{
SetX(42);
SetY(58);
}
int DosomethingWithX() { return GetX() * 2; }
// int DosomethingWithX2() { return X.value * 2; } // error
// int DosomethingWithX3() { return X; } // error
SUPER_PRIVATE(SomeClass, int, X);
SUPER_PRIVATE(SomeClass, int, Y);
};
int main()
{
SomeClass someObject;
int x1 = someObject.GetX();
int y1 = someObject.GetY();
someObject.SetY(89);
int y2 = someObject.GetY();
int x2 = someObject.DosomethingWithX();
}
我会给变量取一个非常难看的名字,给getter/setter取一个漂亮的名字:
class Foo
{
private:
int _hey_do_not_use_me_im_super_private_whatever;
public:
int get_whatever() const
{
//extra logic
return _hey_do_not_use_me_im_super_private_whatever;
}
void set_whatever(int we)
{
//extra logic
_hey_do_not_use_me_im_super_private_whatever = we;
}
};
解释什么是超私有的注释将会受到继承你代码的人的欢迎。
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 用C++中的一个变量定义一个常量
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 你能重载对象变量名本身返回的内容吗
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 尝试通过多个向量访问变量时,向量下标超出范围
- 试图让变量检查数组中的某些内容
- Cpp-Tuple使用带有变量的get
- 将包含C样式数组的对象初始化为成员变量(C++)
- 当vector是tje全局变量时,c++中vector的内存管理
- 我是否必须在类中的所有变量C++设置为 private?
- 当变量在多个函数作用域中使用时,我应该在类 private 中声明该变量吗?
- 在 cpp 文件中命名空间范围内"Private"变量
- C++有没有办法创建'super private'变量?