C++ hiding Dispose is BAD

  • Thread starter Thread starter Ben Voigt [C++ MVP]
  • Start date Start date
B

Ben Voigt [C++ MVP]

Anyone know a direct translation for this C# code? I know I can make a new
function, of course, but that's clumsy.

assume (o is IDisposable)
MethodInvoker d = o.Dispose;

I tried taking the address of the destructor, that either tries to give me
protected void Dispose(bool) with an error (it's the wrong argument list) or
tells me {dtor} is not a member of IDisposable.

This is all on VS2005 SP1.

Automatic implementation of IDisposable screwed up this one!
 
Ben Voigt said:
Anyone know a direct translation for this C# code? I know I can make a
new function, of course, but that's clumsy.

assume (o is IDisposable)
MethodInvoker d = o.Dispose;

I tried taking the address of the destructor, that either tries to give me
protected void Dispose(bool) with an error (it's the wrong argument list)
or tells me {dtor} is not a member of IDisposable.



Does this work?

////////////////////////////////////////////////////////////////////////

ref class disposableclass
{
public:
disposableclass()
{
}
~disposableclass()
{
this->!disposableclass();
}
!disposableclass()
{
}
};

....

disposableclass ^o = gcnew disposableclass();
MethodInvoker ^d = gcnew MethodInvoker(o,
&disposableclass::~disposableclass);

////////////////////////////////////////////////////////////////////////


Mark
 
Mark said:
Does this work?

Your code compiles cleanly. So my situation is actually less general than I
first thought.

Change disposableclass so that it inherits System::Windows::Forms::Form, for
instance. Then:

..\CppTestJunk.cpp(28) : error C2248: 'disposableclass::Dispose' : cannot
access protected member declared in class 'disposableclass'

..\CppTestJunk.cpp(21) : compiler has generated 'disposableclass::Dispose'
here

..\CppTestJunk.cpp(8) : see declaration of 'disposableclass'

..\CppTestJunk.cpp(28) : error C3352: 'void disposableclass::Dispose(bool)' :
the specified function does not match the delegate type 'void (void)'
 
Ben Voigt said:
Your code compiles cleanly. So my situation is actually less general than
I first thought.

Change disposableclass so that it inherits System::Windows::Forms::Form,
for instance.


In that case, Dispose() is hidden (by access level change) by the Form
class and re-exposed through its Close() member, so yeah, that won't work.
 
Mark Salsbery said:
In that case, Dispose() is hidden (by access level change) by the Form
class and re-exposed through its Close() member, so yeah, that won't work.



re-exposed is the wrong wording...I meant iDispose()'s functionality is
re-exposed through Close().

The derived class would need to implemented in a similar fashion.

Mark
[/QUOTE]
 
Mark Salsbery said:
In that case, Dispose() is hidden (by access level change) by the Form
class and re-exposed through its Close() member, so yeah, that won't work.

..NET doesn't allow changing access level at inheritance. But the C++/CLI
compiler is considering the destructor reference to mean protected
Dispose(bool) instead of public Dispose(void).
 
Ben Voigt said:
.NET doesn't allow changing access level at inheritance.

Yeah I always believe that in C#.

What magic does C++ use to make this fail to compile:

System::Windows::Forms::Form ^frm = gcnew
System::Windows::Forms::Form();
frm->Dispose();


???
 
Duh - C++ doesn't let you call Dispose().


///////////////////////////////////////

ref class disposableclass : public System::Windows::Forms::Form
{
public:
disposableclass()
{
}
~disposableclass()
{
this->!disposableclass();
}
!disposableclass()
{
}
};

....
disposableclass ^o = gcnew disposableclass();
o->~disposableclass(); // This is ok
MethodInvoker ^d = gcnew MethodInvoker(o,
&disposableclass::~disposableclass); // This is not ok?

///////////////////////////////////////


Bug?
 
Not sure what you meant by that last comment.

delete (some_tracking_handle);

does exactly call Dispose on the object if it implements IDisposable.
 
Back
Top