4

Suppose you write a class A, with constructor being private (to prevent others to create it on stack) then one day another developer add a new ctor, say A(int), and want to use inside main():

A a(1)

to create it on stack. How do you prevent that?

my solution:

Declare a public constructor

  A(void& input )
   {
 Cerr << “please do not create it on stack” << endl ; 
  exit(1);
   }

I am not sure it is correct ?

thanks

Jack
  • 133
  • 1
  • 7

4 Answers4

8

As others say, you can't prevent people who can edit your class from making it do pretty much anything...BUT...

...if you want a slightly more compiler-enforceable method than a comment, you could inherit from a class which has no default constructor. Anyone writing a constructor would be (hopefully) led to take notice of it. You could make its name cue people into taking certain precautions.

Something like this:

class DoNotStackConstruct {
protected:
    DoNotStackConstruct(const char* dummy) {}
};

class A : protected DoNotStackConstruct {
private:
    A () : DoNotStackConstruct ("PLEASE make all A constructors private!") {
       // your code here
    }
public:
    static std::tr1::shared_ptr<A> newA() {
        return std::tr1::shared_ptr<A>(new A);
    }

/* ... a bunch of code ... */
/* ... then someone later adds the following ... */

public:
    A (int i) {
        // can't force them to make it private, but...
        // this won't compile without mentioning DoNotStackConstruct
    }
};

Once you start using C++11 there will be "delegating constructors", and this trick will have a bit less teeth:

Can I call a constructor from another constructor (do constructor chaining) in C++?

Then they'll be able to delegate to A() without visiting the source line and copying the "hey, don't make your constructor public!" text. But by default, they'll still get the compiler error the first time they try.

Community
  • 1
  • 1
  • The `deleteA` method is completely unnecessary, the constructor is `private`, not the destructor. – Matthieu M. Oct 27 '11 at 06:43
  • @MatthieuM. Originally I had it returning a shared_ptr (which is the only reason I bother with private constructors) but I just paired it to "simplify" further. You're right though, so I'll axe that...tough to decide how much "paint" to use when filling in examples, and tough to decide when to actually bother with compiling it too :-/ – HostileFork says dont trust SE Oct 27 '11 at 06:48
7

Put in a comment that says something like this:

class A
{
    private:
        // This is private on purpose to prevent allocation on the stack.
        // We'll fire you if you ever write a new constructor that isn't private.
        A();
};

This comment is tongue-in-cheek (mostly) but it points to an important concept. Code conventions like disallowing stack allocation need to be enforced by peer review. As others have said, someone else could theoretically change the code however they want. But a good peer review process will help keep that in check. IMHO, that's far more cost effective than some clever compiler tricks that new hires might not necessarily understand.

Michael Kristofik
  • 34,290
  • 15
  • 75
  • 125
  • Indeed, especially as whoever can add a public constructor can obviously modify *any* part of the class, including whatever mechanism implemented to prevent allocation on the stack. – André Caron Oct 27 '11 at 13:21
5

Clearly, you can't prevent it. If someone else can directly edit your code, then they can do whatever they want.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
1

I think the solution you want is the following steps.

  1. Give a constructor 'private' access.
  2. Make a non-member static function who creates a instance by new or malloc and returns it.
  3. Use the function for creating an instance of the class.

I am sure these step may be a solution of your question.

Kyokook Hwang
  • 2,682
  • 21
  • 36