如何在Boost托管共享内存中构造含私有构造函数的对象?
Great question! You absolutely don’t have to abandon your private constructors and factory/destruction methods to use boost::managed_shared_memory. Here are two robust approaches to make this work:
Approach 1: Make Boost’s Managed Memory Class a Friend
The find_or_construct() and construct() methods need to invoke your class’s constructor directly. By granting boost::interprocess::managed_shared_memory (or its underlying segment manager/allocator) friend access to your class, you can keep constructors private while letting Boost do its work.
Here’s a concrete example:
#include <boost/interprocess/managed_shared_memory.hpp> namespace bip = boost::interprocess; class MyRestrictedClass { // Grant friend access to managed_shared_memory so it can call our private constructor friend class bip::managed_shared_memory; private: int m_value; // Private constructor to enforce factory-based creation MyRestrictedClass(int value) : m_value(value) {} public: // Factory method to handle shared memory creation static MyRestrictedClass* CreateInSharedMemory(bip::managed_shared_memory& segment, int value) { // Use find_or_construct as usual—Boost can now call the private constructor return segment.find_or_construct<MyRestrictedClass>("MySharedObject")(value); } // Custom destruction method void DestroyFromSharedMemory(bip::managed_shared_memory& segment) { segment.destroy<MyRestrictedClass>("MySharedObject"); } // Example public method int GetValue() const { return m_value; } };
This approach keeps your encapsulation intact while leveraging Boost’s convenient find_or_construct() API. Your factory method still controls object creation, and external code can’t instantiate the class directly.
Approach 2: Manual Allocation + Placement New
If you prefer not to add Boost classes as friends, you can manually allocate raw memory from the shared segment and use placement new to construct your object. Since static factory methods have access to private constructors, this works perfectly.
Example implementation:
#include <boost/interprocess/managed_shared_memory.hpp> #include <new> namespace bip = boost::interprocess; class MyRestrictedClass { private: int m_value; MyRestrictedClass(int value) : m_value(value) {} public: static MyRestrictedClass* CreateInSharedMemory(bip::managed_shared_memory& segment, int value) { // Allocate raw memory from the shared segment void* raw_mem = segment.allocate(sizeof(MyRestrictedClass)); // Use placement new to construct the object (static method can access private ctor) return new(raw_mem) MyRestrictedClass(value); } void DestroyFromSharedMemory(bip::managed_shared_memory& segment) { // Manually call the destructor this->~MyRestrictedClass(); // Free the raw memory back to the segment segment.deallocate(this); } int GetValue() const { return m_value; } };
Note that with this method, you lose the built-in lookup functionality of find_or_construct(). You’ll need to implement your own logic to track existing objects (e.g., using segment.find() with a custom key) if you need to avoid duplicate creations.
Key Takeaway
You don’t need to make your constructors public. Both approaches preserve your factory/destruction patterns while working seamlessly with Boost’s shared memory utilities. Choose the friend approach for simplicity with Boost’s helper functions, or manual allocation if you want to avoid adding external friends to your class.
内容的提问来源于stack exchange,提问作者S.K

