Подтвердить что ты не робот

Избегание объявления частных функций в заголовочных файлах классов (С++)

(В С++) У меня есть класс, структура которого объявлена ​​в файле заголовка. Этот заголовочный файл включен во множество исходных файлов, так что когда я его редактирую, мне нужно перекомпилировать множество файлов.

Класс имеет набор частных функций, которые вызывается только в одном исходном файле. В настоящее время они объявляются в структуре класса в файле заголовка. Когда я добавляю новую функцию этого типа или редактирую аргументы, это приводит к перекомпиляции большого количества файлов. Я хотел бы объявить функции где-то еще, так что только файл, который определяет и вызывает их, перекомпилируется (чтобы сэкономить время). Тем не менее, они все равно должны иметь доступ к внутренним переменным класса.

Как я могу это достичь?

4b9b3361

Ответ 1

Невозможно объявить функции-члены класса вне объявления основного класса. Итак, если вы хотите объявить за пределами рассматриваемого класса функции, которые могут обращаться к переменным-членам определенного экземпляра класса, тогда я не вижу альтернативы, кроме как передать этот экземпляр функции. Кроме того, если вы хотите, чтобы функции имели доступ к закрытым и защищенным переменным, вам нужно будет поместить их в новый класс и сделать из него оригинальный класс. Например.

header.h:

class FooImpl;

class Foo {
public:
   int bar();
   friend class FooImpl;
private:
   int var;
}

impl.cpp:

#include "header.h"

class FooImpl {
public:
   int bar(Foo &);
}

int FooImpl::bar(Foo &foo) {
return foo.var;
}

int Foo::bar() {
return FooImpl::bar(*this);
}

Ответ 2

Используйте pImpl idiom - Ваш видимый класс хранит указатель на реальный класс и переадресации вызовов на публичные функции-члены.

РЕДАКТИРОВАТЬ: В ответ на комментарии

// Foo.h:

class FooImpl; // Do *not* include FooImpl.h
class Foo {
public:
  Foo();
  ~Foo();
  //.. also need copy ctor and op=
  int bar();
private:
  FooImpl * Impl;
};

// FooImpl.h:

class FooImpl {
public:
  int bar() { return Bar; }
private:
  int Bar;
};

// Foo.cpp:

#include "FooImpl.h"

Foo::Foo() { Impl = new FooImpl(); }
Foo::~Foo() { delete Impl; }
int Foo::bar() { return Impl->bar(); }

Сохранение фактической реализации вашего класса в FooImpl - Foo должно иметь копии публичных членов FooImpl и просто переадресовывать вызовы на них. Все пользователи будут включать только "Foo.h" - вы можете изменить все личные данные FooImpl, если пользователи Foo не видят никаких изменений.

Ответ 4

Создайте абстрактный базовый класс, который содержит только публичные функции и ссылается на это в ваших заголовках. Создайте свой настоящий класс как реализацию где-то еще. Только исходные файлы, которые должны создавать ваш класс, должны видеть заголовок класса реализации.