| References | Casting | Arrays | Import | instanceof | Package | Synchronization | Throwable | finally | Dangerous | Stack | String |
In ACDK, there are some constructs that should be avoided.
class AClass
: public Object
{
public:
int _ival;
AClass()
: Object()
{
foo(this);//oops, this will delete this!!!
_ival = 0; // segmentation fault
}
void foo(RObject o)
/* what happend here is:
o.impl->refCount is 0.
Constructor of RObject increment it to 1.
*/
{
} /* here the destructor of RObject will be called.
The Destruktor decrement o.impl->refCount,
o.impl->refCount is 0 -> delete o.impl.
*/
|
The usage of this in the constructor should be avoided.
Instead, you can use the following construct:
//....
AClass()
: Object()
{
ACDK_SAFE_CONSTRUCTOR(); // to prevent delete this
foo(this);
_ival = 0;
}
//....
|
RString
getAString()
{
RString str2 = new String("Hallo");
return str2;
}
void
foo()
{
RString tstr = getAString();
// we know tstr contains a ascii string, otherwise the string has to be converted
const char* ptr = tstr->c_str(); // This is OK, because tstr holds reference
doIt(getAString()->c_str()); // This is also OK
/*
The following is NOT OK, because the returned RString (and containing buffer)
will be destroyed immediately after returning it.
*/
const char* aptr = getAString()->c_str();
doIt(aptr);// !!!! aptr is dangling pointer !!!!
}
|
Because ACDK objects are C++ objects you can use it following way:
// should not use this, really
StringBuffer* sb = new StringBuffer("Hello ");
delete sb;
|
but in the case you call, which converts the
this pointer of this objects to a RefHolder
(here RStringBufer), the sb object will deletet
by this RefHolder.
StringBuffer* sb = new StringBuffer("Hello ");
sb->append(" World");
// append returns this as RStringBuffer
// sb will be freed by the temporary returned RStringBuffer!
delete sb; // crash!
|
To avoid this you can use following constructs:
StringBuffer* sb = new StringBuffer("Hello ");
sb->addRef(); // prevents for freeing
sb->append(" World");
sb->releaseRef(); // will free the underlying object.
// sb no longer valid
<source>
or alternativally:
<source>
StringBuffer* sb = new StringBuffer("Hello ");
sb->lockMem(true); // locks memory, doen't free by GC
sb->append(" World");
delete sb; //ok
// sb no longer valid
|
|