Re: "Anonyomous" Objects
On Nov 13, 7:35 am, none <n...@none.none> wrote:
Juha Nieminen wrote:
I have a follow-up question that is related to this behavior.
I've switched everything to deal with handles and I have a
"manager" class that keeps track of all the objects, both
temporaries and otherwise.
You shouldn't have any temporaries. Normally, when using a
handle, everything is allocated on the stack. (Also, what you
are doing isn't quite what I meant by handle. The handle I was
thinking of was more along the lines of a smart pointer.)
Using the same example as before, with classes A, B, and C,
what I'm trying to do is have the constructor for class A
simply add "this" to the global manager class, like so:
----- begin code -----
my_global_object_manager_class g_mgr;
class A
{
public:
A() { m_handle = g_mgr.insert(this); }
virtual ~A() {}
virtual void func() { printf("A::func()\n"); }
private:
int m_handle;
};
class B: public A
{
public:
void func() { printf("B::func()\n"); }
};
class C: public B
{
};
int main(int argc, char **argv)
{
// The constructor for A will insert my_C into g_mgr
C my_C;
// Get a pointer to my_C through the manager
A *A_ptr = g_mgr.get_object_by_handle(0);
// This should call my_C.func()
A_ptr->func();
}
----- end code -----
I'm seeing this code display "A::func()". There's nothing
fancy about "my_global_object_manager_class", it's basically
just a std::vector of pointers-to-A. Am I wrong to think that
B::func() should be called here? Is it not valid to use the
"this" pointer of a base class in this way? I have only tried
this in Visual Studio 2005.
I don't see anything wrong here; I'd have to see the exact code
of the manager to be sure. As long as you don't copy the object
anywhere, there should be no problem. With the following
implementation of my_global_object_manager_class, I get
B::func():
class my_global_object_manager_class
{
public:
int insert( A* obj )
{
int result = my_objects.size();
my_objects.push_back( obj );
return result;
}
A* get_object_by_handle( int handle ) const
{
assert( handle >= 0 && handle < my_objects.size() );
return my_objects[ handle ];
}
private:
std::vector< A* > my_objects;
};
(Compiled with VC++ 8, but unless there's a really serious
compiler bug, you should get the same with any compiler.)
BTW: if you're using this strategy, you should also deregister
the object in its destructor. What I had in mind was something
more like the letter/envelope idiom. (The letter/envelope idiom
is a special case of a handle, in which the handle is the base
class of the polymorphic hierarchy.)
--
James Kanze