Programs
with the same structure behave differently in C# and in C++.
Event
handlers of the class System.Windows.Forms.Form are polymorph in C# and
non-polymorph in C++.
Example:
// Two form classes: SecondForm is derived from
FirstForm and it overrides the MouseDownHandler
using System.Windows.Forms;
public class
FirstForm: Form
{
public
FirstForm()
{ //
hang in MouseDown-handler:
this.MouseDown += new MouseEventHandler(this.MouseDownHandler);
}
protected
virtual void
MouseDownHandler(object source, MouseEventArgs
e)
{
MessageBox.Show("First Form", "", MessageBoxButtons.OK);
}
}
public class
SecondForm: FirstForm
{
protected
override void
MouseDownHandler(object source, MouseEventArgs
e)
{
MessageBox.Show("Second Form", "", MessageBoxButtons.OK);
}
public
static void
Main(string[] kzp)
{
System.Windows.Forms.Application.Run(new SecondForm());
}
}
Mouse click on the form produces the
message “Second Form” (as
expected).
The same program in C++:
#using <mscorlib.dll>
#using <System.DLL>
#using
<System.Windows.Forms.DLL>
// First form class
using namespace
System::Windows::Forms;
__gc class FirstForm: public System::Windows::Forms::Form
{
public:
FirstForm();
protected:
virtual void MouseDownHandler(Object* s, MouseEventArgs* e);
};
// First form methods
FirstForm::FirstForm()
{
this -> MouseDown += new MouseEventHandler(this, MouseDownHandler);
}
void FirstForm::MouseDownHandler(Object* s, MouseEventArgs* e)
{
MessageBox::Show("First Form", "", MessageBoxButtons::OK);
}
// Second form class
__gc class SecondForm: public FirstForm
{
protected:
virtual void MouseDownHandler(Object* s, MouseEventArgs* e);
};
// First form method
void SecondForm::MouseDownHandler(Object* s, MouseEventArgs* e)
{
MessageBox::Show("Second Form", "", MessageBoxButtons::OK);
}
// main starts SecondForm
void main()
{
Application::Run(new SecondForm());
}
Mouse click on the form produces the
message “First Form” (in
contrary to the C# version).
The reason for the difference is:
Workaround: call another virtual method in the C++-handler
– this one should be overwritten. MouseDownHandler
does not have to be necessarily virtual:
#using <mscorlib.dll>
#using <System.DLL>
#using
<System.Windows.Forms.DLL>
// First form class
using namespace
System::Windows::Forms;
__gc class FirstForm: public System::Windows::Forms::Form
{
public:
FirstForm();
protected:
void
MouseDownHandler(Object* s, MouseEventArgs* e); // not virtual
virtual
void AnotherMethod(Object* s, MouseEventArgs*
e); // virtual
};
// First form methods
FirstForm::FirstForm()
{
this -> MouseDown += new MouseEventHandler(this, MouseDownHandler);
}
void FirstForm::MouseDownHandler(Object* s, MouseEventArgs* e)
{
AnotherMethod(s, e); // call virtual method
}
void FirstForm::AnotherMethod(Object* s, MouseEventArgs* e)
{
MessageBox::Show("First Form", "", MessageBoxButtons::OK); // event handler
}
// Second form class
__gc class SecondForm: public FirstForm
{
protected:
virtual void AnotherMethod(Object* s, MouseEventArgs* e); // overwrite
};
// First form method
void SecondForm::AnotherMethod(Object* s, MouseEventArgs* e)
{
MessageBox::Show("Second
Form", "", MessageBoxButtons::OK); //
event handler
// main starts SecondForm
void main()
{
Application::Run(new SecondForm());
}
Mouse click on the form produces the
message “Second Form” (as
expected, as in C#).
Sources:
Reply to