Возможно ли как-то сделать следующее:
x.hpp — этот файл включен многими другими классами
class x_impl; //forward declare
class x {
public:
//methods...
private:
x_impl* impl_;
};
x.cpp — реализация
#include <conrete_x>
typedef concrete_x x_impl; //obviously this doesn't work
//implementation of methods...
В общем, я хочу, чтобы пользователи включили файл x.hpp, но не знать о conrete_x.hpp заголовок.
Так как я могу использовать concrete_x
только указателем, и он появляется только как закрытый элемент данных, для того, чтобы компилятор знал, сколько места для его подготовки должно быть достаточно для предварительного объявления. Это выглядит как хорошо известная «идиома pimpl».
ты можешь помочь мне с этим?
PS. Я не хочу использовать void*
и брось это вокруг ..
На самом деле, даже можно полностью скрыть от пользователя:
// Foo.hpp
class Foo {
public:
//...
private:
struct Impl;
Impl* _impl;
};
// Foo.cpp
struct Foo::Impl {
// stuff
};
Я просто хотел бы напомнить вам, что:
Есть способы автоматизировать PIMPL за счет некоторой черной магии (аналогично тому, что std::shared_ptr
делает).
Как альтернатива ответу от @Angew, если имя concrete_x
не должно быть известно пользователям класса x, вы можете сделать это:
в x.hpp
class x_impl;
class x {
public:
x();
~x();
//methods...
private:
x_impl* impl_;
};
в x.cpp
#include <concrete_x>
class x_impl : public concrete_x { };
x:x() : impl_(new x_impl) {}
x:~x() { delete impl_; }
Это будет работать только тогда, когда прямое объявление объявляет фактическое имя класса. Так что либо меняй x.hpp чтобы:
class concrete_x;
class x {
public:
//methods...
private:
concrete_x* impl_;
};
или используйте имя x_impl
для класса, определенного в заголовке <concrete_x>
,
Вот для чего нужны интерфейсы. Определите интерфейс (чисто виртуальный класс) в вашем общем заголовочном файле и передайте его пользователям. Унаследуйте ваш конкретный класс от интерфейса и поместите его в файл заголовка без общего доступа. Реализуйте конкретный класс в файле cpp (вы даже можете определить конкретный класс внутри cpp).