我的目标是在C ++中创建属性,就像在C#中一样 - 具有非平凡的set / get行为。 这里,Property的对象持有refs来掌握prop及其set / get方法。
实现,Property.h的内容:
#include <iostream>
using namespace std;
namespace First {
template <class Master, class Type>
struct Property
{
Master &master;
const Type (Master::*&get) () const;
Type (Master::*&set)(Type value);
Property
(
Master &master,
const Type (Master::*get) () const,
Type (Master::*set)(Type value)
):
get(get),
set(set),
master(master)
{ }
operator const Type() const { cout << "inside" << endl; return (master.*get)(); }
Type operator = (Type value)
{
return (master.*set)(value);
}
};
// Test chamber.
class R
{
float x;
const float getx() const { cout << "returning " << 0 << endl; return 0; }
float setx(float value) { cout << "setting " << value << " in place of " << x << endl; return x = value; }
public:
Property<R, float> X;
R(): X(*this, &R::getx, &R::setx) { }
};
}
我还创建了.cpp文件:
#include "Property.h"
using namespace First;
int main()
{
R r;
r.X = 10;
float y = r.X;
}
程序进行“分配”步骤,打印'设置0到10',但是在调用“检索”步骤时段错误,在“R :: getx()”内部没有区别(或者根本没有)。< / p>
~/Sources$ ./a.out
setting 10 in place of 0
inside
zsh: segmentation fault ./a.out
似乎调用(master。* get())本身会导致失败。这段代码有什么问题?
UPD:测试了对master函数的任何其他调用导致段错误,只有一次调用(master。* set)成功。似乎这个调用使对象状态,成员到ptr,属性本身或月相无效。
答案 0 :(得分:6)
const Type (Master::*&get) () const;
Type (Master::*&set)(Type value);
从上述定义中删除&
。由于&
,每个都绑定到构造函数返回后不存在的构造函数参数。
另请注意,(master.*set)(value)
似乎有效,因为您运气不好。它实际上调用了未定义的行为。但是你很幸运,很快你就会在(master.*get)()
失败时知道这个问题,给出了段错误。
使用:
const Type (Master::*get) () const;
Type (Master::*set)(Type value);
它应该现在可以正常工作,没有任何问题,因为它会导致初始化列表中地址的复制,而不是引用参数!