-
February 2nd, 2010, 10:58 AM
#1
delete doesn't appear to delete
The singleton class based off the CRTP is not provided, nonetheless consider.
Code:
# include <iostream>
# include <map>
# include <string>
# include <vector>
class Base {
public:
virtual ~Base() {}
};
class Derived : public Base {
public:
Derived() {}
~Derived() { std::cout << "o" << std::endl; }
};
enum TEST_KEYS { A, B, C, END_OF_KEYS };
class test : public singleton < test > {
typedef TEST_KEYS test_keys;
Base *key_list[ END_OF_KEYS ];
public :
template < typename ClassType >
test& insert ( test_keys const & key, ClassType * ptr ) {
if ( key_list [ key ] != 0 ) {
throw ( std::runtime_error( "key exists" ) );
}
key_list [ key ] = ptr;
return ( *this );
}
template < typename ClassType >
Derived& Get ( test_keys const & key ) {
if ( key_list [ key ] == 0 ) {
throw ( std::runtime_error( "no match" ) );
}
//I think static_cast here should suffice
return static_cast< ClassType& >( *( key_list [ key ] ) );
}
template < typename ClassType >
void Delete ( test_keys const & key ) {
if ( key_list [ key ] != 0 ) {
delete key_list[ key ];
}
}
};
//later
int main() {
for ( int odx ( 0 ) ; odx < 2; ++odx ) {
test::instance().insert < Derived >( A, new Derived () );
//now remove it...
test::instance().Delete < Derived > ( A ) ;
}
std::cin.get();
}
It appears that the derived class 'Derived' is not being 'Deleted' from the m_list even though it's clear from debugging and stream output that the destructor of the Derived class is called. That said, on the next call to insert (i.e when odx = 1) the exception 'key exists' is thrown. (I'll admit that after a handful of years with C++ I'm embarassed to admit I'm struggle with what appears to be the basics)
How do I resolve this?
-
February 2nd, 2010, 11:11 AM
#2
Re: delete doesn't appear to delete
after deleting the key you should also reset the pointer to 0; otherwise the "key_list [ key ] != 0" check in the insert function will fail ( BTW, note that the key_list array is zero initialized just because the singleton instance is probably a global variable... )
-
February 2nd, 2010, 11:15 AM
#3
Re: delete doesn't appear to delete
I would recommend explicitly 0-initializing the key_list array. Even if it happens automatically, that isn't something you want to take chances with.
Calling delete will definitely *not* automatically NULL-out the pointer passed to it. It simply renders the address held by the pointer invalid, nothing more.
-
February 2nd, 2010, 01:56 PM
#4
Re: delete doesn't appear to delete
superbonzo and Lindley(as always) thanks. On a separate note: Consider this line
Code:
//I think static_cast here should suffice
return static_cast< ClassType& >( *( key_list [ key ] ) );
The _static_cast_ should suffice. Correct?
-
February 2nd, 2010, 01:59 PM
#5
Re: delete doesn't appear to delete
I think it's a bit odd that you've made that a template function *and* are making Derived the return type. I'd think you would make the return type the templated ClassType.
Given that you're using a template to cast down a base class, I'd recommend using dynamic_cast. An extra check won't slow you down too much, and could save you grief later.
-
February 2nd, 2010, 04:08 PM
#6
Re: delete doesn't appear to delete
Originally Posted by Lindley
I think it's a bit odd that you've made that a template function *and* are making Derived the return type. I'd think you would make the return type the templated ClassType.
Could you elaborate on the part starting with 'I'd think ... .ClassType'. Not sure if I follow you...
-
February 2nd, 2010, 04:11 PM
#7
Re: delete doesn't appear to delete
Code:
template < typename ClassType >
Derived& Get ( test_keys const & key ) {
if ( key_list [ key ] == 0 ) {
throw ( std::runtime_error( "no match" ) );
}
//I think static_cast here should suffice
return static_cast< ClassType& >( *( key_list [ key ] ) );
}
This template will only ever compile when instantiated with Derived, or a class further deriving from Derived.
-
February 3rd, 2010, 09:40 AM
#8
Re: delete doesn't appear to delete
Originally Posted by mop65715
The _static_cast_ should suffice. Correct?
Originally Posted by Lindley
Given that you're using a template to cast down a base class, I'd recommend using dynamic_cast. An extra check won't slow you down too much, and could save you grief later.
You could consider using boost::polymorphic_downcast. It asserts the type with a dynamic_cast in debug, but uses a static_cast in release.
The book "C++ coding standard" by Sutter and Alexandrescu describes the same idea in chapter 93 (they call the function checked_cast).
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|