3 ms·
> Shouldn't allocation strategy be decided by the caller, not type definiton? This is how C++ is designed. Unfortunately, it precludes types from taking depend
by dcrazy 2y ago
> Shouldn't allocation strategy be decided by the caller, not type definiton?
This is how C++ is designed. Unfortunately, it precludes types from taking dependencies on their own address, which is critical for e.g. atomics. As far as I know, there is no way to actually force a C++ class to be heap allocated. I’ve tried.
Newer languages like Swift give the type designer the ability to say “the address of this object in memory is important and must remain stable for the lifetime of this object.” This decays to heap allocation.
- mtklein 2y agoThe idiom I am familiar with here is to make the constructor private and provide a public static factory method that allocates on the heap.
- badmintonbaseba 2y ago> As far as I know, there is no way to actually force a C++ class to be heap allocated. Make the destructor (and possibly the constructors) private, have public factory functions that hand out unique_ptr with a custom deleter, or define a public destroying operator delete (C++20) and use unique_ptr with its default deleter.
- spacechild1 2y ago> Unfortunately, it precludes types from taking dependencies on their own address, It does not! You just have to make it non-copyable and non-moveable. std::mutex and std::atomic do exactly this. > As far as I know, there is no way to actually force a C++ class to be heap allocated. I’ve tried. As others have already pointed out: private constructor + factory method. However, this pattern is typically used for different reasons (implementation hiding or runtime polymorphism) and heap allocation is only a side effect. > This decays to heap allocation. No! The object might just as well live on the stack or have static storage duration.
- Maxatar 2y agoC++ does have ways to force heap allocation, but frankly it's just an antipattern. It's easier to reason about value semantics than reference semantics. If you want a class with a stable address that is heap allocated, then do so by writing class that has a private field that is heap allocated, preferably managed by a unique_ptr. Then disable copy assignment and construction and make a judgement call if you want to support move assignment, construction. In effect, the idea is to make this aspect of the type an implementation detail that the user doesn't need to concern themselves with. They just create an instance of the type, and the type deals with the ownership or ensuring that the address is pinned, or whatever other details are needed to make it work. And of course the type does this by delegating that work to unique_ptr or some other means of ownership.
- slaymaker1907 2y agoThe only thing I can think of that really matters which can’t be solved by just wrapping the data in an inner heap allocation (like std::vector) is with the pointer to the vtable for virtual function calls. If anything, I’ve found it’s more useful when I want to bypass such wrapping to force a class to use some particular memory (like from a bulk allocation). The STL is pretty good, but there are warts that which still force the default heap allocator like std::function.