考虑以下情况:
class Helper
{
public:
// Getters and setters are present!
private:
int i;
std::map<int, boost::interprocess::managed_shared_memory> shm;
}
int main()
{
boost::interprocess::managed_shared_memory shmInfo(boost::interprocess::open_or_create, "Test", 1024);
boost::interprocess::map<int, Helper> myMap = shmInfo.construct< boost::interprocess::map<int, Helper> >("Memory");
}
myMap
(int
和Helper
的地图)是在shared_memory上构建的。反过来,我希望Helper
能够保存int
和boost::interprocess::managed_shared_memory
的地图。
当我尝试在std::map
中使用Helper
时,我收到编译错误:
错误C2248: '升压::进程间:: basic_managed_shared_memory :: basic_managed_shared_memory' :无法访问类中声明的私有成员 '升压::进程间:: basic_managed_shared_memory'
我怎样才能做到这一点?
答案 0 :(得分:2)
好的,这是一个有效的版本 Live On Coliru
让我解决您的代码所遇到的一些问题:
让我们从顶部开始
class Helper
{
public:
// Getters and setters are present!
private:
int i;
std::map<
-----------^
使用std::map
对共享内存分配器来说很麻烦,因为它直接在构造函数中进行分配。 boost::container::map
和boost::interprocess::map
没有,所以在使用Boost进程间分配器时你应该更喜欢它们。使用模板别名,您可以减少声明此类共享地图的复杂性:
template <typename T> using shm_alloc = bip::allocator<T, bip::managed_shared_memory::segment_manager>; template <typename K, typename V> using shared_map = bip::map<K, V, std::less<K>, shm_alloc<std::pair<K const, V> > >;
现在你可以&#34;只是&#34;说shared_map<K,V>
您之前曾说过的std::map<K,V>
。
int, boost::interprocess::managed_shared_memory> shm;
--------------------------------------------^
这里有两点:
boost::interprocess::managed_shared_memory
不可复制(因为它拥有共享内存资源)。在我的示例中,我使用shared_ptr<managed_shared_memory>
来解决此问题。如果您确定对象的生命周期将长于包含指针的地图的生命周期,则可以使用原始指针。
在共享内存中的Helper
类中使用标准分配容器是没有意义的(std :: map将简单地指向进程本地堆上的对象并导致UB从另一个进程引用时)。因此 应该 指定一个boost进程间分配器,以将容器元素放入共享内存中。由于技术原因,这意味着您必须指定关键比较器(事件虽然它只是默认值std::less<K>
)。
}
-^
缺少;
:)
int main()
{
boost::interprocess::managed_shared_memory shmInfo(boost::interprocess::open_or_create, "Test", 1024);
boost::interprocess::map
-------------------------^
即使你现在使用boost::interprocess::map
,你仍然没有表明分配器类型。再次(如上所述),您可以使用shared_map
别名。
<int, Helper>
-----------------------------------------^
指针结果类型缺少*
。
myMap = shmInfo.construct< boost::interprocess::map<int, Helper> >("Memory");
----------------------------------------------------------------------------------------------------------------------^
您忘记调用构造函数代理对象。
}
发表评论:
shm
字段的构造函数outer_alloc
(针对助手地图)和inner_alloc
(针对Helper::shm
)#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
namespace bip = boost::interprocess;
using ShMemRef = boost::shared_ptr<bip::managed_shared_memory>;
template <typename T> using shm_alloc = bip::allocator<T, bip::managed_shared_memory::segment_manager>;
template <typename K, typename V> using shared_map = bip::map<K, V, std::less<K>, shm_alloc<std::pair<K const, V> > >;
class Helper
{
public:
using inner_alloc = shm_alloc<std::pair<int, ShMemRef>>;
Helper(inner_alloc const& instance) : shm(instance) {}
private:
int i;
shared_map<int, ShMemRef> shm;
};
int main()
{
ShMemRef shmInfo = boost::make_shared<bip::managed_shared_memory>(bip::open_or_create, "Main", 1024);
using outer_alloc = shm_alloc<std::pair<const int, Helper>>;
outer_alloc oa_instance(shmInfo->get_segment_manager());
shared_map<int, Helper>* myHelpers = shmInfo->construct<shared_map<int, Helper>>("Memory")(oa_instance);
Helper::inner_alloc ia_instance(shmInfo->get_segment_manager());
Helper helper1(ia_instance), helper2(ia_instance), helper3(ia_instance);
myHelpers->emplace(1, helper1);
myHelpers->emplace(2, helper2);
myHelpers->emplace(3, helper3);
}