Sign in to follow this  

Can I escape casting?

This topic is 4839 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I made a garbage collector in C++, with a base type Object. Is there a way to escape the ugly *_casts<>()s? I don't think anymore information is needed, but if so, please tell me.

Share this post


Link to post
Share on other sites
Quote:
Original post by thedevdan
I made a garbage collector in C++, with a base type Object. Is there a way to escape the ugly *_casts<>()s? I don't think anymore information is needed, but if so, please tell me.


Well you can still use the old style C casts:

int * pie = (int *) ptr_to_char;


and although they will perform casting operations when switching types:


const char * my_string = "I like pie";
int my_string_length = ((std::string)my_string).length();


They won't do so with pointers - It won't even verify that the pointers so much as share a common base class:

class A
{
};
class B
{
};

A * my_a_ptr = new A;
B * my_b_ptr = (B *)A;
my_b_ptr->call_func(); //Compiles, and will cause very nasty, undefined, most likely crash-inducing behavior.

Share this post


Link to post
Share on other sites
If you're passing into your GC functions, you won't need a cast. You never need to explictly cast to a parent/base type, only to a child/derived class.


void AddToCollector(Base *pObj);

Derived *x = new Derived;
AddToCollector(x);



If all the data the GC class needs is exposed in the Base object, it never needs to cast back to the derived type (which it can't do anyway, since it doesn't know the type). So, um, yeah, you can avoid using casts... you don't even need them in this case.

Share this post


Link to post
Share on other sites
Quote:
Original post by Namethatnobodyelsetook
If you're passing into your GC functions, you won't need a cast. You never need to explictly cast to a parent/base type, only to a child/derived class.

*** Source Snippet Removed ***

If all the data the GC class needs is exposed in the Base object, it never needs to cast back to the derived type (which it can't do anyway, since it doesn't know the type). So, um, yeah, you can avoid using casts... you don't even need them in this case.


I did need to give more information. In my design, I made it so you can never make any Object outside of the garbage collector. The way you make objects is by calling gc.getNewObject(), passing it a function pointer that returns an Object*. getNewObject returns type ObjectAlias, which act sort of like pointers to Object except I don't try to duplicate pointer syntax.

Thank you for your help, both of you.

EDIT: Having some trouble staying logged in...

Share this post


Link to post
Share on other sites
Couldn't the baseclass constructor add itself to whatever garbage collection system list it needs adding to, leaving the rest of the code to just use "Blah *x=new Blah;" as always? Without knowing what your GC is doing, I can't say if that will work, but it seems nice and clean and automatic... and again, needs no casts.

Share this post


Link to post
Share on other sites
Yes, it could... hmm... I'll look into that.

EDIT: Actually, that wouldn't work, because I would have no way of knowing if my object is reachable. I guess casts are what I need (I realize I could do C casts, but I want to be more specific).

Share this post


Link to post
Share on other sites
Surely this can be done with templates? Something like this...
myObject *x = gc.getNewObject()<myObject>;

...

template <class T>
T *getNewObject() {
//blah blah blah
}

Share this post


Link to post
Share on other sites

#include <list>
#include <algorithm>

struct BaseClass {
virtual ~BaseClass() {}
};

struct DerivedClass1 : BaseClass{
};

struct DerivedClass2 : BaseClass{
};

void Destroy(BaseClass* obj) {
delete obj;
}

class GarbageCollector {
std::list<BaseClass*> m_collection;
public:
template<typename T>
T* Make() {
T* newObject = new T;
m_collection.push_back(newObject);
return newObject;
}
~GarbageCollector() {
std::for_each(m_collection.begin(),
m_collection.end(),
Destroy);
}
);

int main() {
GarbageCollector gc;
DerivedClass1* c1 = gc.Make<DerivedClass1>();
DerivedClass2* c2 = gc.Make<DerivedClass2>();
}





or something.

[Edited by - petewood on September 17, 2004 11:29:42 AM]

Share this post


Link to post
Share on other sites
You could write your own casts, if you're evil like that:


template < typename CastToT , CastFromT > CastToT s_c ( CastFromT arg) { return static_cast< CastToT > ( arg ); }
template < typename CastToT , CastFromT > CastToT d_c ( CastFromT arg) { return dynamic_cast< CastToT > ( arg ); }
template < typename CastToT , CastFromT > CastToT r_c ( CastFromT arg) { return reinterpret_cast< CastToT > ( arg ); }


I froget the 4th one off the top of my head. But I'd kill you if I ended up having to mantain your code.

Share this post


Link to post
Share on other sites

This topic is 4839 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this