C++ 受保护的外部资源使用

C++ 受保护的外部资源使用,c++,design-patterns,c++11,C++,Design Patterns,C++11,我正在使用一些代码,其中我有以下设置 struct data { void change_safe_member(){} void read_data(){} void change_unsafe_member(){} }; struct data_processor { std::shared_ptr<data> get_data(){} void return_data(std::shared_ptr<data>

我正在使用一些代码,其中我有以下设置

struct data
{
      void change_safe_member(){}
      void read_data(){}
      void change_unsafe_member(){}
};

struct data_processor
{
     std::shared_ptr<data> get_data(){}
     void return_data(std::shared_ptr<data> my_data)
     {
           my_data->change_unsafe_member(); // ONLY data_processor should call this function.
     }
};

struct client
{
     void foo(std::shared_ptr<data_processor>& my_processor)
     {
           auto my_data = my_processor->get_data();
           my_data->change_safe_member();
           //my_data->change_unsafe_member(); SHOULD NOT BE POSSIBLE TO CALL
           my_processor->return_data(my_data);
     }
};
struct数据
{
无效更改\u安全\u成员(){}
void read_data(){}
无效更改\不安全\成员(){}
};
结构数据处理器
{
std::shared_ptr get_data(){}
无效返回_数据(标准::共享_ptr我的_数据)
{
my_data->change_unsafe_member();//只有数据处理器应该调用此函数。
}
};
结构客户端
{
void foo(标准::共享处理器和我的处理器)
{
自动生成我的数据=我的处理器->获取数据();
my_data->change_safe_member();
//my_data->change_unsafe_member();不应能够调用
我的\u处理器->返回\u数据(我的\u数据);
}
};
change_unsafe_成员只能由处理器在内部使用,因此我想隐藏它或为客户端禁用它。但我不知道有什么好方法可以不借助丑陋的演员阵容来做到这一点

struct internal_data
{
      void change_unsafe_member(){}
};

struct data : public internal_data
{
      void change_safe_member(){}
      void read_data(){}
};

struct data_processor
{
     std::shared_ptr<data> get_data(){}
     void return_data(std::shared_ptr<data> my_data)
     {
           auto internal_data = std::static_pointer_cast<internal_data>(my_data);
           internal_data->change_unsafe_member(); 
     }
};
struct内部\u数据
{
无效更改\不安全\成员(){}
};
结构数据:公共内部_数据
{
无效更改\u安全\u成员(){}
void read_data(){}
};
结构数据处理器
{
std::shared_ptr get_data(){}
无效返回_数据(标准::共享_ptr我的_数据)
{
自动内部\u数据=标准::静态\u指针\u转换(我的\u数据);
内部_数据->更改_不安全_成员();
}
};
有人知道在这种情况下使用的好模式吗?可能是访客模式还是类似的

编辑:

正如在评论中指出的,我们可以声明朋友类,但是有一个问题。。。以下方法行不通

struct data
{
      void change_safe_member(){}
      void read_data(){}
private:
      friend class data_processor;
      virtual void change_unsafe_member(){}
};

struct data_decorator : public data
{
      data_decorator(const std::shared_ptr<data>& decoratee) : decoratee_(decoratee){}
      void change_safe_member(){decoratee_->change_safe_member();}
      void read_data(){decoratee_->read_data();}
private:
      virtual void change_unsafe_member()
      {
             std::cout << "Hello!"; // Add functionality
             decoratee_->change_unsafe_member(); // Won't work... compiler error
      }
      std::shared_ptr<data> decoratee_;
};

// Another example
struct data_group_decorator : public data
{
      data_group_decorator (const std::vector<std::shared_ptr<data>>& decoratees) : decoratees_(decoratees){}
      void change_safe_member(){decoratee_->change_safe_member();}
      void read_data(){decoratee_->read_data();}
private:
      virtual void change_unsafe_member()
      {
             for(size_t n = 0; n < decoratees_.size(); ++n)
                   decoratees_[n]->change_unsafe_member(); // Won't work... compiler error
      }
      std::vector<std::shared_ptr<data>> decoratees_;;
};
struct数据
{
无效更改\u安全\u成员(){}
void read_data(){}
私人:
朋友级数据处理机;
虚拟无效更改\u不安全\u成员(){}
};
结构数据装饰器:公共数据
{
数据装饰器(const std::shared_ptr&decoratee):装饰者(decoratee){
void change_safe_member(){decorateee_uu->change_safe_member()}
无效读取数据(){decoreee->read_data();}
私人:
虚拟无效更改\u不安全\u成员()
{
std::cout change_unsafe_member();//无法工作…编译器错误
}
std::共享的装饰物;
};
//另一个例子
结构数据\组\装饰器:公共数据
{
数据组装饰器(const std::vector&decoratees):装饰者(decoratees){
void change_safe_member(){decorateee_uu->change_safe_member()}
无效读取数据(){decoreee->read_data();}
私人:
虚拟无效更改\u不安全\u成员()
{
对于(大小n=0;nchange_unsafe_member();//无法工作…编译器错误
}
std::向量修饰;;
};

你的最后一个例子看起来像是你真正想要的是继承的友谊;i、 e.您希望有一个
decorator
派生类的层次结构,这些类都可以调用
数据中的
私有
成员函数。其他地方的回答是(通常为“否”):


多态性可能会在您的特定场景中提供一些缓解,使
类数据\u decorator
成为一个“几乎纯”的虚拟基类,唯一的非虚拟成员是
受保护的更改\u不安全的成员()
,并使其成为
类数据的
朋友。所有decorator都将继承自
数据\u decorator
,并调用其受保护的非虚拟成员。

您可以通过继承实现这一点

struct Y;
struct X {
    friend struct Y;
private:
    change_unsafe_member() {}
};
struct Y {
protected:
    change_unsafe_member(X& x) { x.change_unsafe_member(); }
};
struct some_other : Y {
    X x;
    change_safe_member() { change_unsafe_member(x); }
};

从Y继承的任何类都可以获得X对Y定义为从X有效转发的任何函数的友谊。

将其私有化,并声明
数据处理器
为友元类?在这种简化的情况下确实可以工作,稍后,我将用一个更复杂的例子更新我的问题。您还可以指定
朋友无效数据处理程序::return\u data(…)
来限制
数据处理程序的某个特定成员的“友好性”
仅在包罗万象的爱太多的情况下。您的例子令人困惑-为什么你们都使用嵌入(通过继承)和pimpl(通过拥有显式的
decoratee\uu
成员)试图澄清示例。另请参见。