вторник, 28 апреля 2009 г.

Прозрение


Пишу по-английски, потому что ну не приспособлен еще русский язык к программистскому профессиональному жаргону.

There is one problem using smart pointers on generic classes — if the one is a member variable of some class XX, then you can't simply forward declare class YY you're wrapping with a smart pointer, because C++ compiler will generate a warning "destruction of an unknown type: destructor of YY will not be called" while generating code for the smart pointer on YY.

// XX.h
class YY;

class XX
{
public:
XX(smart_ptr
ptr);

void doSomething();

private:
smart_ptr
m_ptr; // warning here, YY::~YY() is unknown
};

Usually, I was solving the issue by including "YY.h" in place of forward declaration. However, this involves extra cascade header files inclusion that slows down compilation.

// XX.h
#include "YY.h" // potential slowdown of the compilation

class XX
{
public:
XX(smart_ptr
ptr);

void doSomething();

private:
smart_ptr
m_ptr; // no warning here
};

But yesterday I had been taught a much better solution: it is sufficient to declare destructor in XX and define it within XX.cpp.

// XX.h
class YY;

class XX
{
public:
XX(smart_ptr
ptr);
~XX();

void doSomething();

private:
smart_ptr
m_ptr; // no warning here
};

// XX.cpp
#include "XX.h"
#include "YY.h"

XX::~XX()
{
// destructs m_ptr here, YY::~YY() is accessible
}

It is because when compiler doesn't find a particular class' destructor, it generates it as an inline function, and if YY.h is not included at the moment, the warning appears. So, moving destructor to the cpp and having YY.h included before does the trick. The only drawback is that destructor can not be inlined, but this is a good tradeoff in most cases.

Комментариев нет:

Отправить комментарий