Ниже приведены два фрагмента кода (готовые к компиляции).В первом фрагменте, в котором я использую только прямое объявление для структуры, а удаление указателя на эту структуру из базового класса dtor для класса Guest не вызывается.
Во втором фрагменте, когда вместо прямого объявления я использую полноеопределение этого гостевого класса с использованием delete в Base works, как и предполагалось.
Почему?Почему это имеет значение?Разве предварительное объявление не должно быть просто примечанием для компилятора, говорящего, что определение этого класса / структуры находится где-то еще?
Я очень удивлен, что он просто не работает интуитивно.
//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;
}
// Второй - полный def
#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;
}