按数据成员分配的访问器函数 我想增强C++类的成员,以便从//类到它们的赋值导致自定义的吸收器/ SETER的调用。

按数据成员分配的访问器函数 我想增强C++类的成员,以便从//类到它们的赋值导致自定义的吸收器/ SETER的调用。,c++,c++11,C++,C++11,像 及 我找到了一种在成员赋值时强制函数调用的方法,方法是将成员类型转换为持有私有值的类,并重载cast运算符进行读取,重载赋值运算符进行写入 class WrapInt { public: operator int() const { return Value; } void operator=(const int Assign) { Value= Assign; } private: int Value; } 这是可行的,但在一般情况下,我不能为每个成员定制get

我找到了一种在成员赋值时强制函数调用的方法,方法是将成员类型转换为持有私有值的类,并重载cast运算符进行读取,重载赋值运算符进行写入

class WrapInt
{
public: 
    operator int() const { return Value; }
    void operator=(const int Assign) { Value= Assign; }
private:
    int Value;
}
这是可行的,但在一般情况下,我不能为每个成员定制getter/setter,而只能为每个数据类型定制getter/setter

您是否看到了一种改进方法,以便我可以为同一类型的不同成员编写不同的访问器


更新:

我现在找到了一个满足我需求的解决方案。需要特殊setter的成员是使用知道宿主类的类定义的:

template<class Parent> class WrapInt
{
public:
    int operator=(const int Value) {  (This->*Setter)(Value); return Value; }
    operator int() { return Value; }

private:
    int Value;
    Parent* This;
    void (Parent::*Setter)(int Value);
    friend Parent;
};
class Container 
{
    WrapInt a, b, c;
    Container () 
    {
        a.assign_callback = ...;
        b.assign_callback = ...;
        c.assign_callback = ...;
    }
}
在用户方面

Class Instance;
Instance.Member= 3; // Calls the setter SetMember
cout << Instance.Member;
类实例;
Instance.Member=3;//调用setter SetMember

cout代码的修改版本:

class WrapInt
{
public:
    WrapInt(std::function<int()> getter, std::function<void(int)> setter) :
        getter(getter),
        setter(setter)
    {}

    WrapInt(const WrapInt&) = delete;
    WrapInt& operator =(const WrapInt&) = delete;

    operator int() const { return getter(); }
    void operator=(int value) { setter(value); }
private:
    std::function<int()> getter;
    std::function<void(int)> setter;
};

class Class
{ 
public:
    Class() : Member([this](){ return this->GetMember();},
                     [this](int value) {SetMember(value); })
    {}

    WrapInt Member;
    void SetMember(int Value); // TBD
    int GetMember(); // TBD
};
类包装
{
公众:
WrapInt(std::函数getter,std::函数setter):
getter(getter),
setter(setter)
{}
WrapInt(const WrapInt&)=删除;
WrapInt&运算符=(const WrapInt&)=删除;
运算符int()常量{return getter();}
void运算符=(int值){setter(value);}
私人:
函数吸气剂;
函数设置器;
};
班级
{ 
公众:
Class():成员([this](){返回this->GetMember();},
[this](int值){SetMember(value);})
{}
WrapInt成员;
void SetMember(int值);//待定
int GetMember();//待定
};

你可以修改你的类
WrapInt

选项1:在运行时,使用函数对象

class WrapInt
{
public: 
    operator int() const { return Value; }
    void operator=(const int Assign) 
    { 
        assign_callback(Assign); 
        Value = Assign; 
    }

private:
    int Value;
    std::function<void (int)> assign_callback;
}
选项2:在编译时使用继承

class WrapInt
{
public: 
    operator int() const { return Value; }
    void operator=(const int Assign) 
    { 
        assign_callback(Assign); 
        Value = Assign; 
    }

private:
    int Value;
    virtual void assign_callback(int) = 0;
}
在这个变体中,您将在包含类的类体中多次从WrapInt继承

class Container 
{
    class WrapIntA : public WrapInt {
        void assign_callback() { ... };
    } a;
    class WrapIntB : public WrapInt {
        void assign_callback() { ... };
    } b;
    class WrapIntC : public WrapInt {
        void assign_callback() { ... };
    } c;
}

<>不要与语言抗争:C++不支持函数的获取/设置绑定。你只需要容忍

Instance.Member() = 3;

您可以通过提供返回
const
引用的
const
函数
Member()
和返回非
const
引用的非
const
版本来提供


《C++》的一个批评是需要编写样板的数量,尤其是如果你需要为你的类中的每个成员变量都这样做。但实际上,在这一点上,您几乎完全绕过了封装:除非您的函数进行一致性检查,否则您可以将成员
公开。

模板有什么问题吗?此外,我不认为这是有生产力的,它积极地违背惯用的C++。与
int Data=Instance.Member()相比,code>确实有了巨大的改进?为什么不让
int Member()const
无效成员(int值)
?它还有隐藏实现的优点。我认为对类型和变量都使用大写字母已经够糟糕的了,但后来我看到了
class
。yoCh,C++和C++是两种不同的语言,它们有不同的特征。如果你想以C语言允许的方式进行开发,那么就用C语言开发。从技术上讲,
WrapInt
可以是一个名为
Wrapper
的模板类,这样,它可以处理任何类型,而不仅仅是
int
。这与我需要的非常接近,但不幸的是普通类成员不需要括号。因此,我们最终会有有成员和没有成员,这对用户来说将是相当混乱的。最后,我使用了一个接近您的第一个选项的构造。回调必须是指向成员函数的指针。
class WrapInt
{
public: 
    operator int() const { return Value; }
    void operator=(const int Assign) 
    { 
        assign_callback(Assign); 
        Value = Assign; 
    }

private:
    int Value;
    virtual void assign_callback(int) = 0;
}
class Container 
{
    class WrapIntA : public WrapInt {
        void assign_callback() { ... };
    } a;
    class WrapIntB : public WrapInt {
        void assign_callback() { ... };
    } b;
    class WrapIntC : public WrapInt {
        void assign_callback() { ... };
    } c;
}
Instance.Member() = 3;
int Data = Instance.Member();