Я в шоке
Читаю стандарт С# и С++/CLI.
Первые две программы выводят Derived::foo, третья выводит Base::foo.
Глубоко обежден, что поведение C++ (третья) правильное, однако интересно услышать мнение почему так сделано в CLI.
Программа C#
class Base
{
~Base()
{
foo();
}
public virtual void foo()
{
Console.WriteLine("Base::foo");
}
}
class Derived : Base
{
public overide void foo()
{
Console.WriteLine("Derived::foo");
}
}
class Program
{
public static void Main()
{
Base b = new Derived;
b = null;
GC.Collect();
}
}
Программа на C++/CLI:
ref struct Base
{
~Base()
{
foo();
}
virtual void foo()
{
Console::WriteLine("Base::foo");
}
};
ref struct Derived : Base
{
virtual void foo() override
{
Console::WriteLine("Derived::foo");
}
};
int main()
{
Base ^ b = gcnew Derived;
delete b;
}
Программа на C++:
struct Base
{
~Base()
{
foo();
}
virtual void foo()
{
}
};
struct Derived : Base
{
virtual void foo()
{
std::cout << "Derived::foo" << std::endl;
}
};
int main()
{
Base * b = new Derived;
delete b;
}
А если Derived::foo обращается к каким-то ресурсам которые уже удалены.... А говорят verifiable....
class Base
{
~Base()
{
foo();
}
public virtual void foo()
{
Console.WriteLine("Base::foo");
}
}
class Derived : Base
{
Derived () { ... }
~Derived ()
{
o.Dispose();
}
public overide void foo()
{
o.HelloWorld();
Console.WriteLine("Derived::foo");
}
DisposableObject o;
}
class Program
{
public static void Main()
{
Base b = new Derived;
b = null;
GC.Collect(); //тыдыж!!!! :(
}
}
ЗЫ Я знаю разницу между Finalizerом и деструктором
Так меньше писать.