скрытие внутренней реализации класса с использованием пространства имен - PullRequest
4 голосов
/ 11 мая 2010

Я занимаюсь разработкой библиотеки и хотел бы предоставить своим пользователям открытый интерфейс, отдельный от реальной реализации, скрытой в пространстве имен. Таким образом, я мог изменить только класс HiddenQueue без изменения myQueue, которое будет доступно только пользователям.

Если я поместил код C ++ HiddenQueue в файл myQueue.cpp, компилятор пожалуется, что _innerQueue имеет неполный тип. Я думал, что компоновщик смог решить эту проблему. Что я тут не так делаю?

// myQueue.h
namespace inner{
    class HiddenQueue;
};

class myQueue{

public:
    myQueue();
);

private:

    inner::HiddenQueue _innerQueue;

};

///////////////////////////

// myQueue.cpp
namespace inner{
    class HiddenQueue{};
};

Ответы [ 3 ]

6 голосов
/ 11 мая 2010

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

Ваш код говорит, что класс MyQueue имеет член типа InnerQueue, который будет частью структуры памяти объектов MyQueue. Поэтому, чтобы вывести структуру памяти MyQueue, необходимо знать структуру памяти InnerQueue. А это не так, потому что вы говорите: «Ну, это определено в другом месте».

То, что вы пытаетесь сделать, тесно связано с методом PIMPL idiom"/" firewall компилятора ".

Чтобы решить эту проблему, вы должны либо включить HiddenQueue.h в свой заголовок, либо объявить _innerqueue в качестве указателя:

class myQueue {

public:
    myQueue();

private:

    inner::HiddenQueue* _pinnerQueue;
};

Использование указателя возможно, потому что указатель имеет известный объем памяти (зависит от вашей целевой архитектуры), поэтому компилятору не нужно видеть полное объявление HiddenQueue.

1 голос
/ 11 мая 2010

Вам нужно предоставить указатель на _innetQueue, а не сам объект:

std::auto_ptr<inner::HiddenQueue> _innerQueue;

Форма поиска pimpl ideom или d-pointer

1 голос
/ 11 мая 2010

Чтобы иметь возможность стать членом класса, вам нужно иметь определение для него, а не только объявление. (Для указателя или ссылки на класс достаточно объявления).

...