2012-01-25 2 views
0

Я пытаюсь помочь коллеге получить что-то скомпилированное - по существу, он пытался уменьшить зависимости для небольшого исполняемого файла, который нам нужно сделать из более крупной программной системы.Проблема компиляции - typedefs, forward declarations, namespaces?

Я не уверен, что могу полностью объяснить проблему, как я не совсем понимаю ... но я собираюсь показать, что происходит здесь:

Library A:   Файл: Ах

namespace CF { 
    typedef sometype B; 
}; 

библиотека C:   Файл Ch

//Forward declare Class 
class CF::B; 

Class D { 
    public: 
     B* UseB(); 
}; 

библиотека C:   Файл C.cpp

#include "C.h" 
#include "A.h" 
using CF::B; 

B* D::UseB() 
{ 
    return new B; 
} 

К сожалению, я знаю, что это выглядит немного странно, но я пытался упростить ее из набора файлов, которые мы на самом деле имеем дело.

Обычно мы получаем ошибку множественного определения в CF :: B или когда играем с кодом и меняем его, иногда в CPP-файле он просто не распознает тип CF :: B ,

Я предполагаю, что мой первый вопрос: могу ли я переслать объявление typedef, как мы это пробовали, или есть другой способ справиться с тем, что B является typedef в пространстве имен CF, и мы не делаем хотите, чтобы он был напрямую включен в файл Ch?

+0

Имеются ли в заголовках подходящие охранники? –

+0

Да, у всех есть стандартные защитники включения (#ifndef #define #endif). –

+0

Как перенаправить объявление typedef из другого файла, чтобы не было зависимостей в файле заголовка? это, наверное, хороший первый шаг. –

ответ

1

Переднее заявление будет больше похоже

namespace CF { class B; } 

Компилятор не может сделать что-нибудь из CF::B, если он уже не знает CF быть пространством имен.

Вы также не можете переслать объявление typedef, потому что компилятор должен знать, является ли B классом или встроенным. Некоторые встроенные типы имеют специальные правила, например char* или void*.

+0

Это было не полное решение, но оно продвинулось немного дальше, поэтому мы добились большего прогресса - так Я думаю, что это было, безусловно, лучшее, что мне дадут небрежный вопрос :) Большое спасибо за помощь! +1. –

2

Это, вероятно, поможет вам:

ах:

#ifndef NAMESPACE_A 
#define NAMESPACE_A 

namespace A 
{ 
    class B 
    { 
     public: int i; 
    }; 
} 
#endif 

ч:

#ifndef NAMESPACE_A 
#define NAMESPACE_A 
namespace A 
{ 
    class B; 
} 
#endif 

class D 
{ 
    public: 
     A::B* UseB(); 
}; 

main.cpp:

#include "a.h" 
#include "c.h" 
using A::B; 

B* D::UseB() 
{ 
    return new B(); 
} 

int main(int argc, char* argv[]) 
{ 
    D* d = new D(); 
    B* b = d->UseB(); 
    b->i = 1; 
    return 0; 
} 

... отлично работает для меня ;)

+0

Я думаю, что факт, что 'CF :: B' является типедефом, а не определением класса, имеет решающее значение для вопрос... – ildjarn

+0

+1 и благодарю вас за помощь. Я обращу больше внимания на пространство имен, как вы указали :) –