Я бы постарался вообще не полагаться на предварительное объявление исходного класса.Возможно, я пропустил случай, но я думаю, что предварительное объявление полезно только для чисто частного использования, если тип каким-то образом появляется в сигнатуре метода или если ваш класс содержит член, который каким-то образом указывает или ссылается на тип, возможно косвенно.
Я предлагаю перенаправить объявление обертки для класса и определить его только в файле реализации, когда фактический класс или typedef известны.
Скажем, ваш заголовок класса в настоящее время выглядит следующим образом:
// need header because it contains UglyTypeDef:
#include <UglyHeader.h>
class MyClass {
public:
int theMethod(int a);
private:
void uglyMethod(UglyTypeDef &utd);
int someMember;
UglyTypeDef *utdp;
std::vector<UglyTypeDef *> utds;
};
В этом примере мы могли бы сделать с предварительным объявлением, но мы не хотим полагаться на внутренние компоненты UglyHeader.
Я бы изменил MyClass следующим образом:
class MyClass {
public:
int theMethod(int a);
private:
// move the private method into the implementation file
// hide the ugly typedef
// we safely forward declare our own private wrapper
struct UglyTypeDefWrapper;
int someMember;
UglyTypeDefWrapper *utdp;
std::vector<UglyTypeDefWrapper *> utds;
};
Теперь, чтобы заставить это работать, реализация в файле cpp также должна измениться:
#include "MyClass.hpp"
#include <UglyHeader.h>
struct MyClass::UglyTypeDefWrapper {
// if possible save another level of indirection
// and store by value, otherwise use a second indirection
// by cleverly wrapping at the right level of abstraction
// this abstraction can be free in many cases
UglyTypeDef td;
};
namespace {
// we completely hide the private method in this file as
// an implementation detail and pass it whatever it needs
// this also helps the compiler to inline it,
// because it knows it cannot be referenced in
// a different compilation unit
// we need to pass all members as needed
void uglyFormerMethod(int &someMember, UglyTypeDef &utd) {
someMember += utd.whatever();
}
}
int MyClass::theMethod(int a) {
utd->td.doWhatever();
uglyFormerMethod(someMember, *utd);
for(auto utdwp: utds) {
utdwp->td.doIt();
}
}