[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.vb.general.discussion

Classes-Tutorial (simple Physics-Engine

Schmidt

9/19/2011 11:15:00 PM

Hi folks,

this Thread-Opener is an attempt, to shade some
more light on VB6-Classes - I hope, the ones
not yet familiar with class-usage will find this
useful (or at least encouraging) - and that the
ones already experienced with classes will not
get bored <g>.

I will structure the tutorial this way:

- Classes-Tutorial (simple Physics-Engine)
- Classes-Tutorial 1 (Form-Prototype)
- Classes-Tutorial 2 (Introducing a Class)
- Classes-Tutorial 3 (Constructors)
- a.s.o...

So that replies/questions can be targeted at certain
Tutorial-Steps in-between.

Ok, will start now with the first (simple) chapters ...
cannot promise, to contribute a new chapter every day,
but will try to accomplish the task (according to this
Thread-Openers Title here) within the next two weeks.

And maybe I get some help along the way..
(since my vector-math is a bit rusty).


Olaf
13 Answers

Schmidt

9/19/2011 11:31:00 PM

0

This is (just for completeness) a repost of the small
"all in one Form" prototype, which offered the first
"bouncing ball".

Many ideas start this way, nothing wrong
with such spaghetti-snippets - as long as
they remain under 64kByte per module... ;-)


Ok, will put the code for each step from now on
(and without further notice) always at the bottom
of each post - just take care of the naming
of the Code-Modules - and when something does
not want to play after copying over into a
(correctly named) Class-Module, then please
read the VB-comments on top of some of the
Functions - sometimes a few settings per:
<Extras><Procedure-Attributes> are needed,
to make the VB-IDE happy again.

Todo in the next step:
- clean up the Form a little bit, by introducing
a Ball-Class.


Olaf


'*** into a Form, named 'fDemo'
Option Explicit

Private WithEvents TRender As VB.Timer 'for dynamic creation

Private fW, fH '<- just to store the current FormDimensions

Private R 'Ball-Radius
Private cx, cy 'Ball-Center
Private vx, vy 'Ball-Velocity in Pixels per TimerStep

Private Sub Form_Load() 'let's init our Cirlce
R = 16 'set the Radius
cx = 100: cy = 100 'set the center-point
vx = 1: vy = 3 'set the speed-vector
End Sub

Private Sub Form_Resize() 'save the cur. Width/Height in Vars
fW = ScaleWidth
fH = ScaleHeight
End Sub

Private Sub TRender_Timer()
Cls
Draw
Refresh
End Sub

Sub Draw()
cx = cx + vx: If cx < R Or cx > fW - R Then vx = -vx
cy = cy + vy: If cy < R Or cy > fH - R Then vy = -vy

Circle (cx, cy), R, &HD0D0D0
End Sub

'-----------------------------------------------------
'inits, which don't really belong to the problem above
Private Sub Form_Initialize()

'Inits on our Form-Canvas
AutoRedraw = True
ScaleMode = vbPixels
FillColor = vbYellow
FillStyle = vbFSSolid

'we create the RenderLoop-Timer dynamically...
Set TRender = Controls.Add("VB.Timer", "TRender")
TRender.Interval = 10 '... set a small interval
TRender.Enabled = True '... and start it
End Sub

Schmidt

9/20/2011 12:55:00 AM

0

We want to move some of the Code in our
single Form into an additional module
(or structure), mainly to be able, to
let more than only one single Ball bounce.

We could achieve such structuring of
the currently Form-Private Variables:

Private R
Private Cx, Cy
Private Vx, Vy

when we encapsulate it in a Type (an UDT)
this way:

Public Type tBall
R As Double 'Ball-Radius
Cx As Double 'Ball-CenterPoint X
Cy As Double 'Ball-CenterPoint X
Vx As Double 'Ball-Velocity X-component
Vy As Double 'Ball-Velocity Y-component
End Type

And then we could use it in our Form (to be
able to handle two balls):

Private Ball1 As tBall, Ball2 As tBall
a.s.o.

There's nothing wrong with such an UDT-based
approach - in fact, when performance is needed,
one should think twice, what to move into classes,
and what to encapsulate in UDTs, since UDTs
are leaner structures - their member-access goes
directly against a memory-address - and UDT-arrays
lay out their UDT-Members contiguously in memory
(according to the Array-Index-Position), which offers
another performance-benefit (better cache-locality).

When this tutorial is finished - and somebody wants
to rewrite it in a procedural way - no problem -
it's possible to write clean and structured code
also with *.bas-module-encapsulated UDTs and arrays.
But at the cost of:
- some more lines of code (I'd say, about 20-30%
more would be needed)
- some loss of "elegance" (Ok, not that important
for each and everybody)
- some loss of "easy moveability" - into ActiveX-
COMponents (Dlls, OCXes)
- loss of Events-support (very important, at least
for me)
- lesser decoupling of modules (classes can be
implemented more "isolated and selfhosting" -
not least, due to the just mentioned Events

So, class-based approaches will not perform as well
as UDT-based ones - but IMO they offer better
readability and maintainability in the end.

A well-written Application or Library, which wants
to get the best of both worlds, will have to
use a mix, as always...

Ok, back to our Classes now... ;-)
When we look at the definition of the UDT
above (the Type tBall), then we can achieve
our first class-implementation by simply
placing the Type(d)-Members in analogy to
'tBall' - just open a new Class-Module, name it
'cBall' and place the following in it:

Option Explicit

Public R As Double 'Ball-Radius
Public Cx As Double 'Ball-CenterPoint X
Public Cy As Double 'Ball-CenterPoint X
Public Vx As Double 'Ball-Velocity X-component
Public Vy As Double 'Ball-Velocity Y-component

In other languages there's the possiblity,
to define multiple classes per code-module
(in the same way as we can define multiple
UDTs per code module) - but since VB6
allows only one Class-definition per module,
a "Begin-Class ... End-Class" wrapping is
not necessary and therefore omitted.

So, aside from the leading 'Public' Keyword, this
looks pretty similar to our 'tBall'-UDT (read-
and writable member-access is offered to the
outside) - and in fact Classes are not that
much different in this regard from UDTs -
dont know exactly what the memory-overhead
is in C++ (was it 12Bytes or 16Bytes)...
in VB6 it is larger (about 100Bytes, due to
COM-overhead and some additional VB-automatisms).
And some languages dont even have the 'class'-keyword
in their vocabulary - and can offer "intelligent
UDTs" (types or "structs" with "added functions
or procedures in addition to data-members")
nonetheless.

So, for the moment, we take that defintion as a given...
our class offers the same "named-member-access-
over-a-dot" as an UDT, when we define the members
in the way as shown above (there will be time, to
explain "Auto-Properties" or "Properties in general"
at a later occasion).

So we finally move on and clean up our Form a little
bit - also already moving some functional code (the
collision-check) out of our Form - and into our
"intelligent UDT" - as its first Public Class-Procedure
(a 'class Method' is the offical term)...

Public Sub CheckForCollision(CanvasWidth, CanvasHeight)
Cx = Cx + Vx: If Cx < R Or Cx > CanvasWidth - R Then Vx = -Vx
Cy = Cy + Vy: If Cy < R Or Cy > CanvasHeight - R Then Vy = -Vy
End Sub

And we also make use of another Class-feature:
its "initializer-routine", which can be "auto-
inserted" by clicking at the 'Class'-entry in
the Code-Modules ComboBox:

Private Sub Class_Initialize()
R = 16 'initialize the Radius
Cx = 100: Cy = 100 'initialize the center-point
Vx = 1: Vy = 3 'initialize the Velocity-components
End Sub

Ok, that's it here for the moment - below is the Code again:

Todo in the next step:
- clean up the Form a little bit more, introducing
a Vector-Class and Constructors.


Olaf


'***Into a Class, named 'cBall'
Option Explicit

Public R As Double 'Ball-Radius
Public Cx As Double 'Ball-CenterPoint X
Public Cy As Double 'Ball-CenterPoint X
Public Vx As Double 'Ball-Velocity X-component
Public Vy As Double 'Ball-Velocity Y-component

Private Sub Class_Initialize()
R = 16 'initialize the Radius
Cx = 100: Cy = 100 'initialize the center-point
Vx = 1: Vy = 3 'initialize the Velocity-components
End Sub


Public Sub CheckForCollision(CanvasWidth, CanvasHeight)
Cx = Cx + Vx: If Cx < R Or Cx > CanvasWidth - R Then Vx = -Vx
Cy = Cy + Vy: If Cy < R Or Cy > CanvasHeight - R Then Vy = -Vy
End Sub


'***Into a Form, named fDemo
Option Explicit

Private WithEvents TRender As VB.Timer 'for dynamic creation

Private fW, fH '<- just to store the current FormDimensions

Private Ball1 As cBall, Ball2 As cBall

Private Sub Form_Load() 'let's load (and implicitely init) our Balls
Set Ball1 = New cBall
Set Ball2 = New cBall 'on Ball2 we change the default-velocity
Ball2.Vx = -2
Ball2.Vy = -2
End Sub

Private Sub Form_Resize() 'save the cur. Width/Height in Vars
fW = ScaleWidth
fH = ScaleHeight
End Sub

Private Sub TRender_Timer()
Cls
Draw
Refresh
End Sub

Sub Draw()
Ball1.CheckForCollision fW, fH
Ball2.CheckForCollision fW, fH

'drawing remains in our current Form-Canvas
Circle (Ball1.Cx, Ball1.Cy), Ball1.R, &HD0D0D0
Circle (Ball2.Cx, Ball2.Cy), Ball2.R, &HD0D0D0
End Sub

'-----------------------------------------------------
'inits, which don't really belong to the problem above
Private Sub Form_Initialize()

'Inits on our Form-Canvas
AutoRedraw = True
ScaleMode = vbPixels
FillColor = vbYellow
FillStyle = vbFSSolid

'we create the RenderLoop-Timer dynamically...
Set TRender = Controls.Add("VB.Timer", "TRender")
TRender.Interval = 10 '... set a small interval
TRender.Enabled = True '... and start it
End Sub

Schmidt

9/20/2011 2:48:00 AM

0

In an attempt, to further cleanup our Form
(and our already existing cBall-Class),
we will introduce an additional Class now:

cVect

This class will be responsible mainly for the
Collision-math - but of course also to store
the x, y Coords of the different Vectors, which
we will use "all over the place" when the demo
evolves.

As a short (math-related) introducion - there's
two kind of "vector-types" (both will host
their x,y Coords in the same cVect-Class) -
but to understand (from a users point of view)
the behaviour a bit better:
The one kind (in our cBall-example represented
by the C-MemberVariable, our Ball-Centerpoint)
is a Position-Vector ... think about it as
"host of absolute x,y-coords" - and then there's
the other kind of vector: a "host of relative coords" -
aka Direction-Vector (represented in our cBall-Class
over the V-Membervariable, our Ball-Velocity).

So, in other words: 'C' is a Point (vector) -
and 'V' is a vector used for "compositing -
or calculating new Points in our Coord-System.

For example, to get the new (center-)Point, after
moving our simulation one step further, we would
apply the current (relative) Velocity (stored in 'V')
in a Vector-Addition to our Ball-CenterPoint 'C':
Set C = C.Plus(V)
To create the new Center-Point for the Ball-Placement
(and rendering) in each simulation-step anew.

Ok - that much for the moment with regards to
vector-math - let's move on to the real topic
of this Tutorial-Step: Constructors.

VB6 doesn't have them. <g>

Well not entirely true, because one can make
good use of the often hated (and left untouched)
Default-Method, each VB-Class is able to offer,
when setting a special attribute on a given "Public
Method of your choice" on the Class in question
(per <Extras><ProcedureAttributes> in the IDE-menu).

What are constructors for?

Well, if you look at the code in our latest Form
(in Tutorial-Step 2):

Set Ball2 = New cBall 'on Ball2 we change the default-velocity
Ball2.Vx = -2
Ball2.Vy = -2

We see the instantiation line, to create the Ball2-
Object from our cBall-Class - followed by:
"changing two public-members at construction-time,
because we simply want a different behaviour of Ball2,
compared to Ball1".

Now the lines above don't look all that horrible,
but when hacking a lot of similar code in, and
there's not two members to set, but (on average)
maybe 3-5, then constructors, which allow to supply
these "class-settings, to start with" in a single
line (with intellisense-support), would be worthwhile.

Ok, there's different approaches in VB6, to work around
that - the simplest one is perhaps, to just define a
constructor-function for a given class-type in a *.bas
module (globally).

The used method here achieves a better encapsulation,
because the Constructor-Function is defined in the
Class itself - as is the standard in other languages
as well.

example in C++:

class cVect {
public:
float x;
float y;
cVect () {};
cVect (float, float);
};

cVector::cVector (float a, float b) {
x = a;
y = b;
}

Directly above is the Constructor-Method...
All in all not differing that much from our cVect VB6-Class:

Public x As Double
Public y As Double

'constructor, set as class-DefaultMethod in Extras->ProcedureAttributes
Public Function cVect(ByVal x As Double, ByVal y As Double) As cVect
Set cVect = New cVect
With cVect
.x = x
.y = y
End With
End Function


The above class-defined Constructor-method allows us,
to write the following "math-methods" in cVect this way:

Public Function Neg()
Set Neg = cVect(-x, -y)
End Function

Public Function FlipX()
Set FlipX = cVect(-x, y)
End Function

Public Function FlipY()
Set FlipY = cVect(x, -y)
End Function

Public Function Plus(V As cVect)
Set Plus = cVect(x + V.x, y + V.y)
End Function

--------------------------------
Instead doing it this way ...
(example only for the Neg()-method):
Public Function Neg()
Set Neg = New cVect
Neg.x = -x
Neg.y = -y
End Function

So, constructors can ensure less typing-efforts.
There's no need, to over-do this (and introduce
constructors in each and every Class) - but
for cVect (and also cBall) this is very handy.

Note, that the (other) internal methods in cVect
will directly "jump to" (and use) the internal
definition of the constructor-method, which
is BTW named the same way as the Class-Type,
but VB does not have any problem with that -
and this allows for easier "search-replace
stuff" (e.g. when you search with: "check for
whole word" - in case you want to rename a Class
later on).

Ok, so now our Class 'cVect' can internally use its
similarly named cVect-constructor... fine.
But what about usage of this predefined
cVect-Constructor-method from the outside
(globally within your Application)?

Also possible, even over the same constructor-
name 'cVect'.
There's three things, which are prerequisites to
achieve that:
1. the cVect-Constructor-Method needs to be defined
Public in your Class: done
2. the cVect-Method needs the (hidden) "Class-DefaultMethod
Attribute" set (achievable in your IDE over
<Extras><Procedure-Attributes> -> Set as Default
3. You will need an additional Public Variable in a
*.bas Module, defined this way:

Public cVect As New cVect

The last point (3.) is using a declaration with VBs
'New' Keyword before the ClassType in the Var-Definition.

This ensures an automatic IsNothing-check, meaning:
You can use the Variable (in this case 'cVect')
"all over the place" in your App (or Module)
without taking care of proper instancing yourself.

What VB does under the hood for you, in case such a
"specially defined" Variable is about to be used, is:

If IsNothing(cVect) Then
Set cVect = New cVect
End If
....hand out the Variable to the caller...

An IsNothing check does not take up that much
time - it only needs a few CPU-cycles, to
perform an IsZero-check on the 4Byte-ObjectPointer.

So, whilst "overboarding usage" of:
Dim SomeObjVar As New cSomeClass
is not recommended, this VB6-feature has its
use-cases nevertheless.


Ok, not much to explain anymore (I think) in this
tutorial-step.

Todo in the next step:
- further cleanup of the Form, introducing an
"ucCanvas" UserControl and a cBalls-Collection-Class.


Olaf


'***Into a Class, named: cVect
Option Explicit

Public x As Double
Public y As Double

'constructor->set as class-defaultmethod in Extras->ProcedureAttributes
Public Function cVect(ByVal x As Double, ByVal y As Double) As cVect
Set cVect = New cVect
With cVect
.x = x
.y = y
End With
End Function

Public Function Neg()
Set Neg = cVect(-x, -y)
End Function

Public Function FlipX()
Set FlipX = cVect(-x, y)
End Function

Public Function FlipY()
Set FlipY = cVect(x, -y)
End Function

Public Function Plus(V As cVect)
Set Plus = cVect(x + V.x, y + V.y)
End Function


'***Into a Class, named: cBall
Option Explicit

Public R As Double 'Ball-Radius
Public C As cVect 'Ball-CenterPoint (a Position-Vector)
Public V As cVect 'Ball-Velocity (a Direction-Vector)
Public FillColor As Long
Public BorderColor As Long

Private Sub Class_Initialize()
FillColor = vbYellow
BorderColor = &HD0D0D0
End Sub

'constructor->set as class-defaultmethod in Extras->ProcedureAttributes
Public Function cBall(ByVal R As Double, C As cVect, V As cVect, _
Optional FillColor, Optional BorderColor) As cBall
Set cBall = New cBall
With cBall
.R = R
Set .C = C
Set .V = V
If Not IsMissing(FillColor) Then .FillColor = FillColor
If Not IsMissing(BorderColor) Then .BorderColor = BorderColor
End With
End Function

Public Sub Move()
Set C = C.Plus(V)
End Sub

Public Sub CheckForCollision(CanvasWidth, CanvasHeight)
If C.x < R Or C.x > CanvasWidth - R Then Set V = V.FlipX
If C.y < R Or C.y > CanvasHeight - R Then Set V = V.FlipY

Move 'move out of the penetration-zone
End Sub


'***Into a *.bas-Module, named: modGlobals
Option Explicit

Public cBall As New cBall 'global cBall-Constructor (auto-instancing)
Public cVect As New cVect 'global cVect-Constructor (auto-instancing)


'***Into a Form, named: fDemo

Option Explicit

Private WithEvents TRender As VB.Timer 'for dynamic creation

Private fW, fH '<- just to store the current FormDimensions

Private Ball1 As cBall, Ball2 As cBall

Private Sub Form_Load() 'let's load (and explicitely init) our Balls
Set Ball1 = cBall(20, cVect(50, 50), cVect(1, 2))
Set Ball2 = cBall(16, cVect(150, 150), cVect(-2, -1), vbCyan)
End Sub

Private Sub Form_Resize() 'save the cur. Width/Height in Vars
fW = ScaleWidth
fH = ScaleHeight
End Sub

Private Sub TRender_Timer()
Cls
Draw
Refresh
End Sub

Sub Draw()
Ball1.Move
Ball1.CheckForCollision fW, fH

Ball2.Move
Ball2.CheckForCollision fW, fH

'drawing remains in our current Form-Canvas
FillColor = Ball1.FillColor
Circle (Ball1.C.x, Ball1.C.y), Ball1.R, Ball1.BorderColor

FillColor = Ball2.FillColor
Circle (Ball2.C.x, Ball2.C.y), Ball2.R, Ball1.BorderColor
End Sub

'-----------------------------------------------------
'inits, which don't really belong to the problem above
Private Sub Form_Initialize()

'Inits on our Form-Canvas
AutoRedraw = True
ScaleMode = vbPixels
FillColor = vbYellow
FillStyle = vbFSSolid

'we create the RenderLoop-Timer dynamically...
Set TRender = Controls.Add("VB.Timer", "TRender")
TRender.Interval = 10 '... set a small interval
TRender.Enabled = True '... and start it
End Sub


Wolfgang Enzinger

9/24/2011 8:16:00 PM

0

Schmidt <sss@online.de> wrote:

[...]

>Ok - that much for the moment with regards to
>vector-math - let's move on to the real topic
>of this Tutorial-Step: Constructors.
>
>VB6 doesn't have them. <g>
>
>Well not entirely true, because one can make
>good use of the often hated (and left untouched)
>Default-Method, each VB-Class is able to offer,
>when setting a special attribute on a given "Public
>Method of your choice" on the Class in question
>(per <Extras><ProcedureAttributes> in the IDE-menu).

[...]

Great idea, thanks!
Looks like I'll start using the default method in near future ... :-)

Larry Serflaten

9/26/2011 4:57:00 AM

0

Schmidt <s...@online.de> wrote:

> this Thread-Opener is an attempt, to shade some
> more light on VB6-Classes - I hope,

Oops, that should be 'shed some light'...


> I will structure the tutorial this way:

A tutorial in a newsgroup? This is a Q&A forum. Would not a tutorial
be better placed on a personal blog somewhere?

I'm just saying.....

LFS

Schmidt

9/26/2011 8:30:00 AM

0

Am 26.09.2011 06:56, schrieb Larry Serflaten:

> Schmidt<s...@online.de> wrote:
>
>> this Thread-Opener is an attempt, to shade some
>> more light on VB6-Classes - I hope,
>
> Oops, that should be 'shed some light'...

Thanks.

>> I will structure the tutorial this way:
>
> A tutorial in a newsgroup? This is a Q&A forum.
> Would not a tutorial be better placed on a personal
> blog somewhere?
>
> I'm just saying.....

Dunno, don't have a blog... but am glad, that it
at least inveigled you, to post again into this
group (after some longer timeout ;-) ...
(I really am - where were you?)

If yours is the general opinion, then I'm leaving it
"as is" - maybe post a link to the final result only?
(I'm tempted, because it would save some time here on
my end, you know...)

Olaf

(nobody)

9/26/2011 3:21:00 PM

0

"Schmidt" <sss@online.de> wrote in message
news:j58utu$f2t$1@dont-email.me...
> Ok - that much for the moment with regards to
> vector-math - let's move on to the real topic
> of this Tutorial-Step: Constructors.
>
> VB6 doesn't have them. <g>
>
> Well not entirely true, because one can make
> good use of the often hated (and left untouched)
> Default-Method, each VB-Class is able to offer,
> when setting a special attribute on a given "Public
> Method of your choice" on the Class in question
> (per <Extras><ProcedureAttributes> in the IDE-menu).

<snip>

> example in C++:
>
> class cVect {
> public:
> float x;
> float y;
> cVect () {};
> cVect (float, float);
> };
>
> cVector::cVector (float a, float b) {
> x = a;
> y = b;
> }
>
> Directly above is the Constructor-Method...
> All in all not differing that much from our cVect VB6-Class:
>
> Public x As Double
> Public y As Double
>
> 'constructor, set as class-DefaultMethod in Extras->ProcedureAttributes
> Public Function cVect(ByVal x As Double, ByVal y As Double) As cVect
> Set cVect = New cVect
> With cVect
> .x = x
> .y = y
> End With
> End Function
>
>
> The above class-defined Constructor-method allows us,
> to write the following "math-methods" in cVect this way:
>
> Public Function Neg()
> Set Neg = cVect(-x, -y)
> End Function

I think you are moving too fast for some beginners. They don't see the
rational why you are naming your constructor a confusing name like "cVect",
instead of something like "Init". In C++, there is no Class_Initialize()
event, so if you want a constructor, you have to declare a function with the
same name as the class. So basically you are choosing to follow that model;
I think because those who are already familiar with C++ would be glad to do
it in the same way in VB, and it makes things easier to convert to C++ later
if one wants to. However, in VB, one could use the name "Init" with the same
effect.

> Public Function FlipX()
> Set FlipX = cVect(-x, y)
> End Function
>
> Public Function FlipY()
> Set FlipY = cVect(x, -y)
> End Function
>
> Public Function Plus(V As cVect)
> Set Plus = cVect(x + V.x, y + V.y)
> End Function

The above have missing "As cVect".


Schmidt

9/26/2011 7:57:00 PM

0

Am 26.09.2011 17:20, schrieb Nobody:

>> Public x As Double
>> Public y As Double
>>
>> 'constructor, set as class-DefaultMethod in Extras->ProcedureAttributes
>> Public Function cVect(ByVal x As Double, ByVal y As Double) As cVect
>> Set cVect = New cVect
>> With cVect
>> .x = x
>> .y = y
>> End With
>> End Function
>>
>>
>> The above class-defined Constructor-method allows us,
>> to write the following "math-methods" in cVect this way:
>>
>> Public Function Neg()
>> Set Neg = cVect(-x, -y)
>> End Function
>
> I think you are moving too fast for some beginners.
> They don't see the rational why you are naming your
> constructor a confusing name like "cVect", instead
> of something like "Init".

I've thought about it - and 'Init' was a candidate,
as well as 'NewVect' (which I would prefer, when
the renaming in the next step is really desired).
But is 'cVect' (although being similar to the
Class-Name) really that confusing for beginners?

If we'd have no constructor, then we would
instantiate the usual way over:
Set SomeVector = New cVect

With the constructor-mechanism, we can write:
Set SomeVector = cVect(x, y)
which resembles a bit (aside form the omitted
'New') to the normal instancing - because the
already known Classname is also in use here
(at the right-hand-side of the assignment).

With 'New' it is the VB-Instancing - without
'New', it does the same - only that you can
additionally put some parameters in, if you
want.

Init is a bit "anonymous", it doesn't describe
*what* is initialized (or created/constructed).

So, yeah I'm open for 'NewVect' or 'NewBall'
instead of 'cVect' and 'cBall' as the new
constructor-names - but would like to hear
another opinion (BeeJ, MM, anybody else ...
did I lost you already)?


>
>> Public Function FlipX()
>> Set FlipX = cVect(-x, y)
>> End Function
>>
>> Public Function FlipY()
>> Set FlipY = cVect(x, -y)
>> End Function
>>
>> Public Function Plus(V As cVect)
>> Set Plus = cVect(x + V.x, y + V.y)
>> End Function
>
> The above have missing "As cVect".

Yep, good catch - will change the return-
type from "anonymous variant" to cVect
in the next step.

Olaf

Bob Butler

9/26/2011 8:11:00 PM

0


"Schmidt" <sss@online.de> wrote in message
news:j5qle4$dmh$1@dont-email.me...
> Am 26.09.2011 17:20, schrieb Nobody:
<cut>
> I've thought about it - and 'Init' was a candidate,
> as well as 'NewVect' (which I would prefer, when
> the renaming in the next step is really desired).
> But is 'cVect' (although being similar to the
> Class-Name) really that confusing for beginners?

Can't speak for anybody else but I find the constructor name being the same
as the class name confusing even when I work in C (which I do fairly often
and have for years). It's a poorly designed convention IMO.

I also think that this whole tutorial business is inappropriate for the
newsgroup.

ralph

9/26/2011 10:33:00 PM

0

On Mon, 26 Sep 2011 11:20:56 -0400, "Nobody" <nobody@nobody.com>
wrote:

>
>I think you are moving too fast for some beginners. They don't see the
>rational why you are naming your constructor a confusing name like "cVect",
>instead of something like "Init". In C++, there is no Class_Initialize()
>event, so if you want a constructor, you have to declare a function with the
>same name as the class. So basically you are choosing to follow that model;
>I think because those who are already familiar with C++ would be glad to do
>it in the same way in VB, and it makes things easier to convert to C++ later
>if one wants to. However, in VB, one could use the name "Init" with the same
>effect.
>

I too prefer to call 'constructors' "Init", using the same name for
all my classes that need one.

1) Like NoBody I feel it fits the VB schema better.

2) Because most of my class names tend to be larger than 4 characters,
thus universally using "Init" - universally saves typing.

3) During development I often use templates, cannibalize classes,
renaming, etc. Using "Init" for all class constructors cuts down on
re-editing.

4) Last I find it easier to read. Open any class and the "Init"/s
sticks out. (At least to me. <g>)

In the example so far only one contructor is used or needed. Later on
there may be situations where more than one is useful ... so I like to
mark the difference with a "By" suffix.

For example (highly contrived) one might have a 'timekeeper' class
that employs the following constructors...
' Class CTimeStore
InitByCurrentDate
InitByDate( dDate As Date )
InitByDate( sDate As String )
InitByCopy( cls As CTimeStore )

Once again one could just as easily use the same name as the class.
Once again it is just my preference to use Init instead. The important
thing we will all agree on is that one needs to be consistent across
all development. Employment of Constructors, especially those critical
to creating a valid instance, is entirely dependent on the discipline
of the developer. Anything that improves the ability to be more
disciplined is a good thing. <g>

-ralph