【发布时间】:2011-05-25 05:20:14
【问题描述】:
我正在使用一些具有以下设置的代码。
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();
}
};
有人知道在这种情况下使用的好模式吗?也许是访问者模式或类似的东西?
编辑:
正如 cmets 中所指出的,可以声明朋友类,但是有一个问题......以下将不起作用。
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_;;
};
【问题讨论】:
-
将其设为私有并声明
data_processor为好友类? -
这在这个简化的情况下确实可以工作,我稍后会用一个更复杂的例子来更新我的问题。
-
您还可以指定
friend void data_processor::return_data(.....),仅当所有包容的爱都太多时,才将“友好”限制为data_processor的特定成员。 -
您的示例令人困惑 - 为什么您都使用嵌入(通过继承)和 pimpl(通过具有显式
decoratee_成员)? -
试图澄清示例。另请参阅en.wikipedia.org/wiki/Decorator_pattern。
标签: c++ design-patterns c++11