【发布时间】:2012-02-29 09:15:54
【问题描述】:
大家好!
属性未在 C++ 中实现。我估计我们不能写
myObject.property = value; // try to set field f_ to value
is property 是私有数据成员。公共数据成员违反 OOP 封装规则。
相反,我们必须编写 getter/setter 代码:
myObject.setField(value); // try to set field f_ to value
这篇文章是关于C++ 中的属性模拟。 属性调用看起来像公共数据成员调用,但自定义 UDF 代码用于设置或获取真正的私有数据成员值。
我们想做的是允许简单的接口使用(像公共数据成员,没有函数调用语法),而底层的 getter/setter 可能很复杂(不仅仅是数据分配/读取).
下面的代码(我的同事写的)展示了简单的属性实现:
#include <iostream>
template<class C, class M>
inline C* get_parent_this(typename M C::*member_ptr, M*const member_this)
{
//interpret 0 as address of parent object C and find address of its member
char* base = reinterpret_cast<char*>(nullptr);
char* member = reinterpret_cast<char*>( &(reinterpret_cast<typename C*>(base)->*member_ptr) );
//modify member_this with offset = (member - base)
return reinterpret_cast<typename C*>(reinterpret_cast<char*>(member_this) - (member - base) );
}
class Owner
{
int x,pr_y;
int get_y() {return pr_y;}
void set_y(int v) {pr_y = v;}
public:
struct
{
operator int() { return get_parent_this(&Owner::y, this)->get_y(); }
void operator =(int v) { get_parent_this(&Owner::y, this)->set_y(v); }
} y;
};
int main ()
{
Owner ow;
ow.y = 5;
std::cout << ow.y;
if( get_parent_this(&Owner::y, &ow.y) == &ow) std::cout << "OK\n";
if( (char *)&ow.y != (char *)&ow) std::cout << "OK\n";
return 0;
}
在上面的示例中有一个简单的 getter/setter 对,它不做任何额外的工作(例如完整性检查或边界检查),但此代码可能是复杂的执行边界检查、完整性检查等。 这只是测试示例。
不用担心get_parent_this 帮助模板中的“奇怪”代码。最“可怕”的事情是偏移计算。 nullptr (NULL, 0x0) 地址用作存根。我们不会从该地址写入或读取。我们只将它用于根据子对象地址计算所有者对象偏移量。我们可以使用任何地址代替 0x0。所以,这没有意义。
属性用法:
- 如果有人使用公共数据成员属性在以下情况下可能会有所帮助: 1.1。如果出现错误,则跟踪公共数据成员调用; 1.2.轻松升级基于公共数据成员使用的遗留代码;
- 您如何看待 C++ 中的属性仿真?是活泼的想法吗?这个想法有缺点吗(请展示一下)?
- 您如何看待从主题地址计算所有者对象地址?您知道哪些技巧和可能的陷阱?
请告诉我们你的想法!
谢谢!
【问题讨论】:
-
我不太明白。公共数据成员有什么问题?
-
幸运的是,在惯用的 C++ 中,您经常会发现“属性”和 getter/setter 都不像您想象的那样必要。
-
我仍然震惊和恐惧地盯着
&(reinterpret_cast<typename C*>(base)->*member_ptr)。 -
@pmr 除了设置实际值之外,没有在 set 方法中做过其他事情吗?
-
@DaddyM 未定义的行为。 stackoverflow.com/questions/2397984/… 举了几个例子,很好地解释了这个词的含义。
标签: c++ properties emulation object-properties