[comp.lang.c++] calling constructor

ttwang@polyslo.CalPoly.EDU (Thomas Wang) (10/14/89)

I still have not solved the problem of directly calling the constructor.

This requirement came from my garbage collection project.  For each garbage
collectable class 'foo', there is a reference class 'ref_foo'.  When a 'foo'
object is created, it must be registered with its reference handle.

If I do the registration after the construction of 'foo', I will have a
problem.  It is possible to trigger garbage inside the 'foo' constructor, when
the new object is not yet registered.  There are some complications, but the
end result is that live objects will be deleted.

The proper sequence must be: create space, register with reference, call
object constructor.

If I cannot call constructors directly with AT&T compiler,
I will be forced to only implement for g++.


 -Thomas Wang (Ranma no baka!
                 - Ranma 1/2 )

                                                     ttwang@polyslo.calpoly.edu

bgibbons@Apple.COM (Bill Gibbons) (10/14/89)

In article <1989Oct13.175853.24335@polyslo.CalPoly.EDU> ttwang@polyslo.CalPoly.EDU (Thomas Wang) writes:
>I still have not solved the problem of directly calling the constructor.
>...
>The proper sequence must be: create space, register with reference, call
>object constructor.
>...
>If I cannot call constructors directly with AT&T compiler,
>I will be forced to only implement for g++.

You can't explicitly call a constructor, but you can overload the NEW operator
and give it an extra argument.  If that argument is a pointer (the original
reason for allowing this), the overloaded NEW can just return its argument.
Naturally, the constructor is invoked next and you get the effect you wanted.
See section 5.3.3 of the AT&T reference manual for CFront 2.0 .

For example:

	class T {
	public:
		T();
		void *operator new(unsigned int, void *where) { return where; }
		void operator delete(void*);
	};
	
	void f()
	{
		void *p;
		T *t = new (p) T;
	}

You can also explicitly call the destructor, as in:

	t->T::~T();

Note that the new and delete functions must be public.  As with other
overloaded functions, multiple flavors of new and delete can be declared
for a given class.


Bill Gibbons
bgibbons@apple.com

ark@alice.UUCP (Andrew Koenig) (10/17/89)

WARNING -- THE FOLLOWING TECHNIQUE IS RECOMMENDED ONLY FOR
PEOPLE WHO ARE SURE THEY KNOW WHAT THEY'RE DOING.

To construct an object of class T at location x, do the following:

	void* operator new(size_t, void* p) { return p; }

	// ...

		new(x) T;	// construct the object

This effectively calls T::T() and tells it to do its thing
at location x.
-- 
				--Andrew Koenig
				  ark@europa.att.com

wmm@sdti.com (William M. Miller) (10/23/89)

In article <1989Oct13.175853.24335@polyslo.CalPoly.EDU> ttwang@polyslo.CalPoly.EDU (Thomas Wang) writes:
>I still have not solved the problem of directly calling the constructor.
>
>This requirement came from my garbage collection project.  For each garbage
>collectable class 'foo', there is a reference class 'ref_foo'.  When a 'foo'
>object is created, it must be registered with its reference handle.
>
>If I do the registration after the construction of 'foo', I will have a
>problem.  It is possible to trigger garbage inside the 'foo' constructor, when
>the new object is not yet registered.  There are some complications, but the
>end result is that live objects will be deleted.
>
>The proper sequence must be: create space, register with reference, call
>object constructor.
>
>If I cannot call constructors directly with AT&T compiler,
>I will be forced to only implement for g++.

The ability to overload operator new() on a per-class basis in 2.0 is
exactly what you need here, rather than calling constructors directly.
All you need to do is define your operator new() to do the first two
steps (creating the space and registering the reference).  Since
operator new() is called before the constructor, the correct order is
guaranteed, and the normal mechanism of constructor invocation need not
be tampered with.  And, since operator new() can be inherited, you can
provide the necessary functionality in the base garbage collectable
class and not worry about it for derived classes.

-- 
Non-disclaimer:  My boss and I always see eye-to-eye (every time I look in
the mirror).

wmm@sdti.sdti.com

shap@delrey.sgi.com (Jonathan Shapiro) (10/25/89)

In article <1989Oct13.175853.24335@polyslo.CalPoly.EDU> ttwang@polyslo.CalPoly.EDU (Thomas Wang) writes:
>I still have not solved the problem of directly calling the constructor.
>
...
>
>The proper sequence must be: create space, register with reference, call
>object constructor.

In C++2.0:

Try overloading operator new() to call ::new to get the space, do the
registration, and return, after which the constructor will get called
for you.

Jonathan S. Shapiro
Synergistic Computing Associates