I found another bug.
If you declare arrays of classes, only one constructor gets called. This is the example I was using.
#use "ccl.lib"
declare extern ListCreate(),pointer;
declare extern ListGetFirst(pointer pList),pointer;
declare extern ListGetNext(pointer pList),pointer;
declare extern ListGetData(pointer pList),pointer;
declare extern ListAdd(pointer pList, pointer pData),pointer;
declare extern ListRemoveAll(pointer pList, int bDelete);
declare extern ListRemove(pointer pList),pointer;
pointer _err_list;
// This class will work, since it uses global variables.
// We can't use a list class since it's global.
class Error
{
pointer m_pNode;
declare Error();
declare _Error();
declare Dispatch(int code);
declare virtual OnError(int code);
}
// This class won't work however.
class Error2
{
int m_iCode;
declare Dispatch(int code);
declare virtual OnError(int code);
}
Error::Error()
{
if (_err_list = 0) _err_list = ListCreate();
m_pNode = ListAdd(_err_list, this);
}
Error::_Error()
{
ListRemove(m_pNode);
}
Error::Dispatch(int code)
{
pointer p, d;
for (p = ListGetFirst(_err_list); p <> null; p = ListGetNext(p))
{
d = ListGetData(p);
*(Error)d.OnError(code);
}
}
Error::OnError(int code)
{
// Do nothing
}
Error2::Dispatch(int code)
{
// well, we can't do much here, just call my error method.
OnError(code);
}
Error2::OnError(int code)
{
}
////////////////////////////////////////
// Now derive classes from the above. //
////////////////////////////////////////
class MyErr : Error
{
declare OnError(int code);
}
class MyErr2 : Error2
{
declare OnError(int code);
}
MyErr::OnError(int code)
{
MessageBox(0, str$(code,0), "Error");
}
MyErr2::OnError(int code)
{
MessageBox(0, str$(code,0), "Error2");
}
global sub main()
{
MyErr m;
MyErr auaiosef;
m.Dispatch(1); // Will pop up twice since there are two classes.
MyErr2 m2;
MyErr2 m2asijafs;
m2.Dispatch(1); // Will only pop up once since there is no way to get ahold of the other classes.
}
If you change the definitions to MyErr m[2]; and MyErr2 m2[2]; then only one messagebox will popup for each class, otherwise it works fine.
it's not a bug, in Error you use global variable that is visible for whole source file, but it is not a good idea in classes.
Use always local variables with pointer to common data; this pointer must be initialized outside#include "lists.inc"
// This class won't work however.
class Error2
{
pointer *m_err_list; // pointer to shared ListCreate()
int m_iCode;
declare Dispatch(int code);
declare virtual OnError(int code);
}
Error2::Dispatch(int code)
{
pointer p, d;
for (p = ListGetFirst(*(pointer)m_err_list); p <> null; p = ListGetNext(p))
{
d = ListGetData(p);
*(Error2)d.OnError(code);
}
}
Error2::OnError(int code)
{
}
////////////////////////////////////////
// Now derive classes from the above. //
////////////////////////////////////////
class MyErr2 : Error2
{
declare OnError(int code);
}
MyErr2::OnError(int code)
{
MessageBox(0, str$(code,0), "Error2");
}
global sub main()
{
MyErr2 m2a;
MyErr2 m2b;
// create shared linked list and
// say to m2a and m2b where it is
pointer CommonList = ListCreate();
ListAdd(CommonList, m2a);
ListAdd(CommonList, m2b);
m2a.m_err_list = &CommonList;
m2b.m_err_list = &CommonList;
m2a.Dispatch(1);
ListRemoveAll(CommonList, false);
}
It was an example, Error2 and MyErr2 weren't supposed to work, that's what it was demonstrating, but if you make an array of MyErr, only one messagebox will pop up, when 2 should.
Arrays of classes don't work yet. Even if you create them with NEW. Not that I have ever needed an array of classes before.
So it is not a bug, just that we are still in the Alpha stage and OOP functionalitly is stated as being completed by Alpha 3. If you read through the update announcement I think I do state that classes are only constructed if created on the stack (locally) or by themsleves with NEW.
Paul.
Okay, thanks for clearing that up. As I said before, it was just an example of what would work and what wouldn't, and I discovered something new :)
I remember that global classes aren't supported, and they are created in the main method, that's why I thought it was a bug. Good to know you're aware of it though. Thanks.