Проблема компиляции - typedefs, предварительные объявления, пространства имен? - PullRequest
0 голосов
/ 25 января 2012

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

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

Библиотека A: Файл: A.h

namespace CF {
    typedef sometype B;
};

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

//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?

Ответы [ 2 ]

2 голосов
/ 25 января 2012

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

хиджра:

#ifndef NAMESPACE_A
#define NAMESPACE_A

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

c.h:

#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;
}

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

1 голос
/ 25 января 2012

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

namespace CF { class B; }

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

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

...