Ниже представлены два фрагмента (готовые к компиляции) кода. В первом фрагменте, в котором я использую только декларацию forward для структуры, при удалении указателя на эту структуру из базового класса dtor для класса Guest не вызывается.
Во втором фрагменте, когда вместо объявления forward я использую полное определение этого класса Guest, используя delete в Base works ase.
Почему? Почему это имеет значение? Разве декларация не является просто запиской для компилятора, говорящей, что определение этого класса/структуры находится где-то в другом месте?
Я очень удивлен, что он просто не работает интуитивно.Вперед декларация просто не будет
//First just forward dclr
#include "stdafx.h"
#include <iostream>
using std::cout;
struct Guest;
struct Base
{
Guest* ptr_;
Base(Guest* ptr):ptr_(ptr)
{
cout << "Base\n";
}
~Base()
{
cout << "~Base\n";
delete ptr_;
}
};
struct Guest
{
Guest()
{
cout << "Guest\n";
throw std::exception();
}
Guest(int)
{
cout << "Guest(int)\n";
}
~Guest()
{
cout << "~Guest\n";
}
};
struct MyClass : Base
{
Guest g;
MyClass(Guest* g):Base(g)
{
cout << "MyClass\n";
}
~MyClass()
{
cout << "~MyClass\n";
}
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
Guest* g = new Guest(1);
MyClass mc(g);
}
catch(const std::exception& e)
{
std::cerr << e.what();
}
return 0;
}
// Второй - полный Защиту
#include "stdafx.h"
#include <iostream>
using std::cout;
struct Guest
{
Guest()
{
cout << "Guest\n";
throw std::exception();
}
Guest(int)
{
cout << "Guest(int)\n";
}
~Guest()
{
cout << "~Guest\n";
}
};
struct Base
{
Guest* ptr_;
Base(Guest* ptr):ptr_(ptr)
{
cout << "Base\n";
}
~Base()
{
cout << "~Base\n";
delete ptr_;
}
};
struct MyClass : Base
{
Guest g;
MyClass(Guest* g):Base(g)
{
cout << "MyClass\n";
}
~MyClass()
{
cout << "~MyClass\n";
}
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
Guest* g = new Guest(1);
MyClass mc(g);
}
catch(const std::exception& e)
{
std::cerr << e.what();
}
return 0;
}
Вы должны сделать ваши конструкторы базового класса виртуальными в обоих случаях. –
@ Space_C0wb0y: Дорогой, вы не можете сделать конструктор виртуальным в C++ :) –
@Armen: Слова ... дым и зеркала. Это было так ясно в моем сознании. (Для тех, кто задается вопросом, это должны быть * деструкторы *) –