按数据成员分配的访问器函数 我想增强C++类的成员,以便从//类到它们的赋值导致自定义的吸收器/ SETER的调用。
像 及 我找到了一种在成员赋值时强制函数调用的方法,方法是将成员类型转换为持有私有值的类,并重载cast运算符进行读取,重载赋值运算符进行写入按数据成员分配的访问器函数 我想增强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
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();