S
st_ev_fe
Hi people,
I've been doing C for about 7 years now. But I'm new to C++.
I've decided that C++'s operator overloading could be very handy. I'm
writing something much like auto_ptr, except for my own set of classes.
Basically, it's a class that is supposed to be allocated automatically
on the stack, and possesess one member which is a pointer to an object.
Unlike auto_ptr, my object will actually call a lock or unlock function
upon the object. Each object has a "long RefCount" member, and a
"MyClass*" which is a pointer to some type information. The "class"
pointed to is just a statically allocated struct that contains some
nice info about each instance of itself, such as the size, the
constructor and destructor functions.
Basically I've written a ref-counting memory management system in C++.
I think anyone familiar with the STL string class shouldn't be too
worried about this approach, because most "string" implementations
actually use refcounts internally, anyhow.
And this is my first venture into properly using C++. So by default,
I'll be getting things wrong )
Well the code is correct. It compiles, and runs as I expect it to (took
some debugging but it's there now).
So what's my question?
Basically, is there a faster / smaller / neater way to do what I'm
doing? I've tested my code when setting the compiler to generate small
size code (for Mac PPC), and... well the refcounting system seems to
use A LOT of code just to do something very simple like:
Ref1 = Ref2;
Just that takes up about 52 bytes of in my compiled PPC executable!
Normally assigning a pointer takes 4 bytes, (that's 1 PPC instruction).
Well, obviously that's quite bad right?
The code executing is htis:
class OPObject {
OPStruct* Value;
OPObject& operator=(OPObject& obj) {
OPUnlock(Value);
Value = ref.Value;
OPLock(Value);
return *this;
}
This is actually an inline function. This is my first question, is it
even worth inlining this function?? Especially when I'm using two
inlined functions, OPLock and OPUnlock?
OPLock goes like this:
inline void OPLock( OPStruct* obj ) {
if (obj) {
obj->RefCount++;
}
}
inline void OPUnlock( OPStruct* obj ) {
if (obj) {
long rc = obj->RefCount - 1;
obj->RefCount = rc;
if (!rc) {
OPDeAlloc( obj );
}
}
}
Doesn't seem like much code, but it adds up...
It's a lot just to do "a = b;", really.
Of course, I don't necessarily need to use my OPObjects everywhere...
OPObject is just for memory management really. I can just extract the
OPStruct* and pass that around, knowing that it's a bare pointer that
could be invalid if stored outside of the lifetime of the OPObject.
Would I get faster code if I uninlined some stuff??
What about altering my code? Does anyone know a faster way to do
refcounting? Any OOP experts out there that know a faster way to do
this?? Any OOP experts out there that know how other refcounting
languages do their refcounting? Maybe if someone knows how Java or perl
or VisualBasic or other languages do it....??
The "if (obj)" thing irks me because I just wonder if there is a way to
do without it... but it seems like I must have it, because it's quite
possible to have an OPStruct* to 0, so I need to be able to handle
that. Unless someone can think of a clever way to avoid having to deal
with that? (One that doesn't involve me recoding my entire library
which currently relies on comparing object pointers to 0 to see if they
exist or not.)
Also, this brings me back to the question of neatness and simplicity.
I just don't know really how to make this into a compile-time type
checking safe system.
Right now I have a base class, OPStruct. All my other classes subclass
from this, so I have:
struct MySpecialClass : public OPStruct { /*...*/ };
struct MyOtherClass : public OPStruct { /*...*/ };
etc etc
Now, OPObject (with it's "OPStruct* Value"), doesn't actually specify
any type other than OPStruct.
OPObject has a handy converter to and from OPStruct*, so there is no
problem passing and returning the two types between each other.
So that means I can stuff a "MySpecialClass" into OPObject...
And then call this function MySpecialFunction(OPStruct* obj); like so
MySpecialFunction( MyOPObject ); // OPObject's operator convert to
OPStruct* is called.
because I've not specified any types in MySpecialFunction's params. if
I DID specify a type in MySpecialFunction's param, like so:
MySpecialFunction( MySpecialClass* obj );
then I can't call this:
MySpecialFunction( MyOPObject );
then I'll get a type error, because OPStruct* isn't necessarily a
MySpecialClass*!!
So what do I do?
I want compile-time type checking with a small simple way to manage
this. Can I do it with some special define trickery that lets me define
OPStruct* subclasses with their corresponding OPObject subclassing
owners?
Or is there a better way using templates? I don't want any overhead,
this must strictly be a compile-time type check remember.
Sorry for taking so long to explain myself but I think if I used less
works I wouldn't have stated the situation fully )
Thanks in advance to anyone smart enough and helpful enough to reply!
I've been doing C for about 7 years now. But I'm new to C++.
I've decided that C++'s operator overloading could be very handy. I'm
writing something much like auto_ptr, except for my own set of classes.
Basically, it's a class that is supposed to be allocated automatically
on the stack, and possesess one member which is a pointer to an object.
Unlike auto_ptr, my object will actually call a lock or unlock function
upon the object. Each object has a "long RefCount" member, and a
"MyClass*" which is a pointer to some type information. The "class"
pointed to is just a statically allocated struct that contains some
nice info about each instance of itself, such as the size, the
constructor and destructor functions.
Basically I've written a ref-counting memory management system in C++.
I think anyone familiar with the STL string class shouldn't be too
worried about this approach, because most "string" implementations
actually use refcounts internally, anyhow.
And this is my first venture into properly using C++. So by default,
I'll be getting things wrong )
Well the code is correct. It compiles, and runs as I expect it to (took
some debugging but it's there now).
So what's my question?
Basically, is there a faster / smaller / neater way to do what I'm
doing? I've tested my code when setting the compiler to generate small
size code (for Mac PPC), and... well the refcounting system seems to
use A LOT of code just to do something very simple like:
Ref1 = Ref2;
Just that takes up about 52 bytes of in my compiled PPC executable!
Normally assigning a pointer takes 4 bytes, (that's 1 PPC instruction).
Well, obviously that's quite bad right?
The code executing is htis:
class OPObject {
OPStruct* Value;
OPObject& operator=(OPObject& obj) {
OPUnlock(Value);
Value = ref.Value;
OPLock(Value);
return *this;
}
This is actually an inline function. This is my first question, is it
even worth inlining this function?? Especially when I'm using two
inlined functions, OPLock and OPUnlock?
OPLock goes like this:
inline void OPLock( OPStruct* obj ) {
if (obj) {
obj->RefCount++;
}
}
inline void OPUnlock( OPStruct* obj ) {
if (obj) {
long rc = obj->RefCount - 1;
obj->RefCount = rc;
if (!rc) {
OPDeAlloc( obj );
}
}
}
Doesn't seem like much code, but it adds up...
It's a lot just to do "a = b;", really.
Of course, I don't necessarily need to use my OPObjects everywhere...
OPObject is just for memory management really. I can just extract the
OPStruct* and pass that around, knowing that it's a bare pointer that
could be invalid if stored outside of the lifetime of the OPObject.
Would I get faster code if I uninlined some stuff??
What about altering my code? Does anyone know a faster way to do
refcounting? Any OOP experts out there that know a faster way to do
this?? Any OOP experts out there that know how other refcounting
languages do their refcounting? Maybe if someone knows how Java or perl
or VisualBasic or other languages do it....??
The "if (obj)" thing irks me because I just wonder if there is a way to
do without it... but it seems like I must have it, because it's quite
possible to have an OPStruct* to 0, so I need to be able to handle
that. Unless someone can think of a clever way to avoid having to deal
with that? (One that doesn't involve me recoding my entire library
which currently relies on comparing object pointers to 0 to see if they
exist or not.)
Also, this brings me back to the question of neatness and simplicity.
I just don't know really how to make this into a compile-time type
checking safe system.
Right now I have a base class, OPStruct. All my other classes subclass
from this, so I have:
struct MySpecialClass : public OPStruct { /*...*/ };
struct MyOtherClass : public OPStruct { /*...*/ };
etc etc
Now, OPObject (with it's "OPStruct* Value"), doesn't actually specify
any type other than OPStruct.
OPObject has a handy converter to and from OPStruct*, so there is no
problem passing and returning the two types between each other.
So that means I can stuff a "MySpecialClass" into OPObject...
And then call this function MySpecialFunction(OPStruct* obj); like so
MySpecialFunction( MyOPObject ); // OPObject's operator convert to
OPStruct* is called.
because I've not specified any types in MySpecialFunction's params. if
I DID specify a type in MySpecialFunction's param, like so:
MySpecialFunction( MySpecialClass* obj );
then I can't call this:
MySpecialFunction( MyOPObject );
then I'll get a type error, because OPStruct* isn't necessarily a
MySpecialClass*!!
So what do I do?
I want compile-time type checking with a small simple way to manage
this. Can I do it with some special define trickery that lets me define
OPStruct* subclasses with their corresponding OPObject subclassing
owners?
Or is there a better way using templates? I don't want any overhead,
this must strictly be a compile-time type check remember.
Sorry for taking so long to explain myself but I think if I used less
works I wouldn't have stated the situation fully )
Thanks in advance to anyone smart enough and helpful enough to reply!