It seems easy to make sure that an object can only be created on the stack and not on the heap (by simply marking private operator new), but is it possible to do the opposite: only permitting the creation of an object on the heap (with operator new) and *not* on the stack, with compiler warnings for the forgetful programmer?

If you have something like a factory pattern then you can enforce it, for example:

class CandyFactory{
 private:
  struct ChoclateBar(){ 
        int calories; 
        ChoclateBar(): calories(){}
   };
 public:
  shared_ptr<ChoclateBar> makeChoclateBar(){
       return shared_ptr( new ChoclateBar() )
  }
};

I don't know if thats what you were asking?

Edited 5 Years Ago by firstPerson: n/a

I don't see much purpose for it. Stack-based objects are so much nicer to use than heap-allocated objects. I'd be curious to know about your use-case?

The solution is to use a factory function and private constructors, as suggested by firstPerson (and, of course, smart-pointers are strongly preferred to raw-pointers).

If you have C++11 support, there is a very nice idiom to create a factory function, as so:

class MyRational {
  private:
    int num;
    int denom;
    
    MyRational(int aNum = 0, int aDenom = 1) : num(aNum), denom(aDenom) { };
  public:
    //..
    MyRational(const MyRational&) = delete;
    MyRational(MyRational&&) = delete;
    MyRational& operator=(const MyRational&) = delete;
    MyRational& operator=(MyRational&&) = delete;

    template <typename... Args>
    static std::unique_ptr<MyRational>&& Create(Args&&... args) {
      return std::unique_ptr<MyRational>(new MyRational(std::forward<Args>(args)...));
    };
};

int main() {

  std::unique_ptr<MyRational> r1 = MyRational::Create(2);
  std::unique_ptr<MyRational> r2 = MyRational::Create(1,2);

  return;
};

Edited 5 Years Ago by mike_2000_17: n/a

To firstperson: Yep, that seems to do the trick! Thanks.
To mike:
the use case was the desire to centralise all memory allocation to get more information on memory use/availability.
Regarding C++11. My problem is that this is all theoretical for me. I use VS2009 which does not support it. Do newer version of VS support it? Do you know when they expect to support it? Will it be more close to 2 year or 10 years. (Remember that template partial specialisation support tooks may years to be available and the template are still not not bug free in Vs2009 (with Msft expressly telling me that they have no plan to correct the defect discovered by Vanjiyan121).

VC10 supports some of the basic language features such as rvalue-refs. VC11 will add a few insignificant language features, but at least, in VC11, the C++11 standard library will be pretty much complete (put aside the things that cannot be implemented with the limited C++11 language feature support). But almost all interesting features will still be lacking at least until VC12, like variadic templates, template aliases, delegating ctors, inherited ctors, default/delete functions, and initializer lists.

I share your skepticism of MSVC's ability to every reach a reasonable compliance, given their track-record on delivering support for C++98, with about a 10 year delay (since MSVC2008 is about the first decent compiler they produced in that respect). But I think that most features of C++11 should be reasonably easy to add, at least, the GCC team managed to get more of them done pretty quickly, just lacking a few things.

So, I know C++11 is still theoretical for most, but I think it's good to start showing C++11 code (and how it solves some problems pretty neatly) just to build enthusiasm and make the switch as swift as possible (with more pressure on compiler-vendors).

This question has already been answered. Start a new discussion instead.