Is it possible to prevent stack allocation of an object and only allow it to be instiated with 'new' on the heap?
-
2The reverse, which may also be interesting to readers: http://stackoverflow.com/questions/10985/how-to-prevent-an-object-being-created-on-the-heap – kevinarpe Aug 16 '16 at 14:36
6 Answers
One way you could do this would be to make the constructors private and only allow construction through a static method that returns a pointer. For example:
class Foo
{
public:
~Foo();
static Foo* createFoo()
{
return new Foo();
}
private:
Foo();
Foo(const Foo&);
Foo& operator=(const Foo&);
};

- 10,315
- 5
- 39
- 45
-
14
-
**Related question:** [How do I prevent a class from being allocated via the 'new' operator? (I'd like to ensure my RAII class is always allocated on the stack.)](http://stackoverflow.com/questions/124856/how-do-i-prevent-a-class-from-being-allocated-via-the-new-operator-id-like) – Sergey M Dec 03 '13 at 23:22
-
-
1Because if it's heap allocated then the object should not be copied, only its pointer should be copied. – Dominik Grabiec Feb 24 '15 at 03:57
In the case of C++11
class Foo
{
public:
~Foo();
static Foo* createFoo()
{
return new Foo();
}
Foo(const Foo &) = delete; // if needed, put as private
Foo & operator=(const Foo &) = delete; // if needed, put as private
Foo(Foo &&) = delete; // if needed, put as private
Foo & operator=(Foo &&) = delete; // if needed, put as private
private:
Foo();
};

- 7,813
- 9
- 47
- 65
-
9As Scott Meyers stated in "Item 11: Prefer deleted functions to private undefined ones." his book "Effective Modern C++", it's better to declare deleted member functions `public`. --QUOTE-- "By convention, deleted functions are declared `public`, not `private`. There’s a reason for that. When client code tries to use a member function, C + + checks accessibility before deleted status. When client code tries to use a deleted `private` function, some compilers complain only about the function being `private`, even though the function’s accessibility doesn’t really affect whether it can be used." – Siu Ching Pong -Asuka Kenji- Mar 28 '15 at 15:10
-
4--QUOTE-- "It’s worth bearing this in mind when revising legacy code to replace `private`-and-not-defined member functions with deleted ones, because making the new functions `public` will generally result in better error messages." – Siu Ching Pong -Asuka Kenji- Mar 28 '15 at 15:13
-
2
You could make the constructor private
, then provide a public
static factory method to create the objects.

- 81,399
- 26
- 107
- 114
The following allows public constructors and will stop stack allocations by throwing at runtime. Note thread_local
is a C++11 keyword.
class NoStackBase {
static thread_local bool _heap;
protected:
NoStackBase() {
bool _stack = _heap;
_heap = false;
if (_stack)
throw std::logic_error("heap allocations only");
}
public:
void* operator new(size_t size) throw (std::bad_alloc) {
_heap = true;
return ::operator new(size);
}
void* operator new(size_t size, const std::nothrow_t& nothrow_value) throw () {
_heap = true;
return ::operator new(size, nothrow_value);
}
void* operator new(size_t size, void* ptr) throw () {
_heap = true;
return ::operator new(size, ptr);
}
void* operator new[](size_t size) throw (std::bad_alloc) {
_heap = true;
return ::operator new[](size);
}
void* operator new[](size_t size, const std::nothrow_t& nothrow_value) throw () {
_heap = true;
return ::operator new[](size, nothrow_value);
}
void* operator new[](size_t size, void* ptr) throw () {
_heap = true;
return ::operator new[](size, ptr);
}
};
bool thread_local NoStackBase::_heap = false;

- 1,539
- 15
- 10
-
I don't think you need `_stack` as a data member. Having it as a simple stack variable inside the `NoStackBase` constructor should do. – Paul J. Lucas Jan 25 '16 at 15:16
-
1You also don't need to make the destructor `virtual`. Nobody can delete a derived class via a `NoStackBase` anyway. – Paul J. Lucas Jan 25 '16 at 15:48
-
since you explicitly call global operator new, I assume this won't call any custom operator overload those objects have defined (?), and forcing the use of those may be the motivating reason for this question – Joseph Garvin Jan 24 '20 at 16:00
This should be possible in C++20 using a destroying operator delete, see p0722r3.
#include <new>
class C
{
private:
~C() = default;
public:
void operator delete(C *c, std::destroying_delete_t)
{
c->~C();
::operator delete(c);
}
};
Note that the private destructor prevents it from being used for anything else than dynamic storage duration. But the destroying operator delete allows it to be destroyed via a delete expression (as the delete expression does not implicitly call the destructor in this case).

- 7,176
- 33
- 27
You could create a header file that provides an abstract interface for the object, and factory functions that return pointers to objects created on the heap.
// Header file
class IAbstract
{
virtual void AbstractMethod() = 0;
public:
virtual ~IAbstract();
};
IAbstract* CreateSubClassA();
IAbstract* CreateSubClassB();
// Source file
class SubClassA : public IAbstract
{
void AbstractMethod() {}
};
class SubClassB : public IAbstract
{
void AbstractMethod() {}
};
IAbstract* CreateSubClassA()
{
return new SubClassA;
}
IAbstract* CreateSubClassB()
{
return new SubClassB;
}

- 39
- 6