是否可以选择在运行时函数可以访问类的私有成员? [英] Is it possible to chose at runtime function that can access private members of a class?
问题描述
我有一个类,它有一些私人数据。这个主题可能是一个混乱,但我相信我之后的概念很容易掌握。我想提供一种方法来指定一个函数从一个类的外部,可以操作这个数据,在运行时。
到目前为止,我有这样的东西:
#include< iostream>
using namespace std;
class Base {
double priv = 0;
public:
Base(double initial):priv(initial){};
double get_private(){return priv; };
static void mix_privates(Base& b1,Base& b2);
};
void Base :: mix_privates(Base& b1,Base& b2){
b1.priv = b2.priv =(b1.priv + b2.priv)/ 2;
}
// void Base :: mix_privates(Base& b1,Base& b2){
// b1.priv = b2.priv = max(b1.priv, b2.priv);
//}
int main(){
Base test1(5),test2(10);
Base :: mix_privates(test1,test2);
cout<< test1.get_private()<< '\\\
';
cout<< test2.get_private()<< '\\\
';
return 0;
}
到目前为止,我不需要改变或选择实现将函数声明为静态成员,但现在我喜欢上面的例子,我可以提供 mix_privates
的几个不同的实现。此外,我有许多类似于 Base
的对象,并且可以很容易地将它们泛化为 mix_privates
>
理想情况下,我想能够做的是定义几个 mix_privates
实现。例如像这样:
模板< typename BaseLike>
void mix_privates_max(BaseLike& b1,BaseLike& b2){
b1.priv = b2.priv = max(b1.priv,b2.priv);
}
template< typename BaseLike>
void mix_privates_avg(BaseLike& b1,BaseLike& b2){
b1.priv = b2.priv =(b1.priv + b2.priv)/ 2;
}
然后在 main
将一个具体实现分配给一些通用名称,例如:
std :: function< void(Base& mix_privates = mix_privates_avg< Base>
然后使用混合器通用名 mix_privates(test1,test2)
通过程序的剩余部分。
如果 mix_privates
只使用公共成员属性,我做到了。但我想要能够混淆私人数据。
我在考虑使用友谊,但它是不可继承的,这是一个缺点,不可转让,所以我想我不能指定一个像代理一样的朋友函数。
有一种方法来实现这个或东西类似c ++ 11?
与其他建议相反,我会考虑 mix_privates
一个模板,它接受一个函数,它将做实际的混合:
template< typename Functor&
void Base :: mix_privates(Base& b1,Base& b2,Functor f){
b1.priv = b2.priv = f(b1,b2);
}
然后您可以使用它:
基本b1(..),b2(..);
Base :: mix_privates(b1,b2,
[](double x,double y){return(x + y)/ 2;}); // average
Base :: mix_privates(b1,b2,
& std :: max< double>); // max
The topic might be a it confusing but I believe the concept I am after is pretty easy to grasp.
I have a class, that has some private data. I would like to provide a way to specify a function from the outside of a class that can operate on this data, during the run time. However, I would not like to expose the data to the public.
So far I had something like this:
#include <iostream>
using namespace std;
class Base{
double priv = 0;
public:
Base(double initial) : priv(initial) {};
double get_private(){ return priv; };
static void mix_privates(Base& b1, Base& b2);
};
void Base::mix_privates(Base& b1, Base& b2){
b1.priv = b2.priv = (b1.priv+b2.priv)/2;
}
//void Base::mix_privates(Base& b1, Base& b2){
// b1.priv = b2.priv = max(b1.priv, b2.priv);
//}
int main() {
Base test1(5), test2(10);
Base::mix_privates( test1, test2 );
cout << test1.get_private() << '\n';
cout << test2.get_private() << '\n';
return 0;
}
Up to this point I did not need to change or choose the implementation so I declared the function as a static member, but now I like in the example above I can provide several different implementations of mix_privates
. Moreover I have many objects similar to Base
and can easily generalize mix_privates
for them, for example via template.
Ideally I would like to be able to do is to define few mix_privates
implementations. For example like this:
template<typename BaseLike>
void mix_privates_max(BaseLike& b1, BaseLike& b2){
b1.priv = b2.priv = max(b1.priv, b2.priv);
}
template<typename BaseLike>
void mix_privates_avg(BaseLike& b1, BaseLike& b2){
b1.priv = b2.priv = (b1.priv + b2.priv)/2;
}
And then in main
assign a concrete implementation to some general name, e.g:
std::function<void(Base&, Base&)> mix_privates = mix_privates_avg<Base>
and then use mixer through general name mix_privates(test1, test2)
through out rest of the program.
There is no problem if mix_privates
uses only public members and attributes, and I got it done. But I would like to be able mess with private data. There is also no point in exposing it to public except for this functionality, so I would like to avoid it.
I was thinking about using friendship, but it is not inheritable, which is a drawback, and not transferable, so I think I cannot specify a friend function that would act like a proxy.
Is there a way to implement this or something similar in c++11?
Contrary to the other suggestions, I would consider making mix_privates
a template that takes a function that will do the actual mix:
template <typename Functor>
void Base::mix_privates(Base& b1, Base& b2, Functor f) {
b1.priv = b2.priv = f(b1,b2);
}
Then you can use it:
Base b1(..), b2(..);
Base::mix_privates(b1,b2,
[](double x, double y) { return (x+y)/2; }); // average
Base::mix_privates(b1,b2,
&std::max<double>); // max
这篇关于是否可以选择在运行时函数可以访问类的私有成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!