私は次の設定があるコードで作業しています。私はそれを隠すかのクライアントのためにそれを無効にしたいと思いますので、保護された外部リソースの使用
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);
}
};
change_unsafe_memberは、プロセッサだけで内部的に使用する必要があります。しかし、私は
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();
}
};
誰もがこのような状況で使用するために良好なパターンを知っている...醜いキャストに頼ることなくこれを行うのいずれかの素敵な方法を知らないのか?たぶん訪問者のパターンまたは何か似ている?
はEDITは:1友達クラスを宣言することができ、コメントで指摘
として、しかしそこにある一つの問題...以下は動作しません。
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_;;
};
からYが前方として効果的に定義する任意の機能のためにXの友情を得ることができますか –
これは実際にこの単純化されたケースではうまくいくはずですが、私はちょっと複雑な例で質問を更新します。 – ronag
また、 'friendly_data_processor :: return_data(.....)'を指定することで、すべての愛があまりにも大きい場合にのみ 'friendly_ness 'を' data_processor'の特定のメンバーに制限することができます。 –