Короткий ответ: «Нет!»
Причина: любые / все «клиентские» проекты, которые должны использовать ваш класс Class
, должны иметь полное объявление этого класса для того, чтобы компилятор мог правильно определять такие вещи, как смещения для переменных-членов.
Использование private
членов хорошо - клиентские программы не смогут их изменить- как и ваша текущая реализация, где в заголовке представлены только краткие описания функций-членов со всеми фактическими определениями в вашем (личном) исходном файле.
Возможный способ обойти это - объявить указатель на вложенный класс в Class
, где этот вложенный класс просто объявлен в общем заголовке: class NestedClass
и тогда вы можете делать то, что вам нравится, с помощью этого вложенного указателя класса в вашемреализация.Как правило, указатель на вложенный класс можно сделать членом private
;кроме того, поскольку его определение не дано в общем заголовке, любая попытка «клиентского» проекта получить доступ к этому классу (кроме как в качестве указателя) будет ошибкой компилятора.
Вот возможная разбивка кода (возможно, еще не без ошибок, поскольку это быстрый набор):
// impl.h
struct MyInternal; // An 'opaque' structure - the definition is For Your Eyes Only
class Class {
public:
Class();
init();
doSomething();
private:
MyInternal* hidden; // CLient never needs to access this! Compiler error if attempted.
}
// impl.cpp
#include <api.h>
#include <impl.h>
struct MyInternal {
SomeLibrary::Type myData;
};
Class::Class() {
init();
}
Class::init() {
hidden = new MyInternal; // MUCH BETTER TO USE unique_ptr, or some other STL.
hidden->myData = SomeLibrary::Type(42);
}
Class::doSomething() {
hidden->myData.doSomething();
}
ПРИМЕЧАНИЕ. Как я уже говорил в комментарии к коду, было бы лучше использовать код std::unique_ptr<MyInternal> hidden
.Тем не менее, это потребует от вас явных определений в вашем Class
для деструктора, оператора присваивания и других (оператор перемещения? Конструктор копирования?), Так как для этого потребуется доступ к полному определению MyInternal
структура.