是否可以选择在运行时函数可以访问类的私有成员? [英] Is it possible to chose at runtime function that can access private members of a class?

查看:173
本文介绍了是否可以选择在运行时函数可以访问类的私有成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有一个类,它有一些私人数据。这个主题可能是一个混乱,但我相信我之后的概念很容易掌握。我想提供一种方法来指定一个函数从一个类的外部,可以操作这个数据,在运行时。



到目前为止,我有这样的东西:

  #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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆