How to Create C++ style constructors

BlitzMax Forums/BlitzMax Programming/How to Create C++ style constructors

Czar Flavius(Posted 2010) [#1]
I've cracked it! Here's a simple, unimaginative example.

Strict
Type TShape
	Field _x, _y
	
	Method Draw() Abstract
	
	Method Create:TShape(x, y)
		_x = x
		_y = y
		Return Self
	End Method
End Type

Type T2D Extends TShape
	Field _w, _h
	
	Method Create2d:T2D(x, y, w, h)
		Create(x, y)
		_w = w
		_h = h
		Return Self
	End Method
End Type

Type TRectangle Extends T2D
	Method Draw()
		DrawRect _x, _y, _w, _h
	End Method
	
	Method CreateRect:TRectangle(x, y, w, h)
		Create2d(x, y, w, h)
		'unique rectangle stuff
		Return Self
	End Method
	
End Type

Type TSquare Extends T2D
	Method Draw()
		DrawRect _x, _y, _h, _w
	End Method
	
	Method CreateSquare:TSquare(x, y, s)
		Create2d(x, y, s, s)
		'unique square stuff
		Return Self
	End Method
End Type

Graphics 640, 480

Local shape1:TShape = New TRectangle.CreateRect(50, 50, 100, 20)
Local shape2:TShape = New TSquare.CreateSquare(250, 50, 50)
shape1.Draw()
shape2.Draw()
Flip
WaitKey()


Don't comment on my OOP inheritence design, it's just a simple example I made up to show the idea :P

Advantages:
* Base constructor called before derived
* All prior constructors guaranteed (from point-of-use)
* Different constructors possible (give them different names, remember to call base)

Disadvantages:
* Due to lack of overloading, each Create method needs a unique name, which can become tedius.

This is compared to the old method I used which used chaining. It would look something like this.
Local shape:TShape = New TRectangle.Create(w, h).sub_create(x, y)


Which not only looks ugly, means you need to remember the base constructor and the base is also constructed last. If you want it first, you're going to need uglier casts.

Or the "good old" Create Function.

Function Create:TRectangle(x, y, w, h)
	Local rectangle:TRectangle = New TRectangle
	rectangle._x = x
	rectangle._y = y
	rectangle._w = w
	rectangle._h = h
	Return rectangle
End Function


Which has no easy way of representing the concept of base constructors. You'll have to duplicate the x/y setting up for each final shape type.

Summary -
* Use Methods that return Self.
* Derived constructor calls base constructor first thing.
* Derived constructor needs at least as many parameters as the base constructor (unless you want to set them yourself inside the method) and passes them down to base.

Last edited 2010