基于C ++模板指针到成员的属性实现的一些麻烦

时间:2011-08-15 08:57:21

标签: c++ templates properties

我的目标是在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,属性本身或月相无效。

1 个答案:

答案 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);

它应该现在可以正常工作,没有任何问题,因为它会导致初始化列表中地址的复制,而不是引用参数!