Как избежать объявления частных функций в файлах заголовков классов (C ++) - PullRequest
23 голосов
/ 14 апреля 2011

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

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

Как мне этого добиться?

Ответы [ 4 ]

14 голосов
/ 14 апреля 2011

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

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

// 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 должны иметь копии public членов FooImpl и просто переадресовывать вызовы на них. Все пользователи будут включать только «Foo.h» - вы можете изменить все личные данные FooImpl, при этом пользователи Foo не увидят никаких изменений.

4 голосов
/ 16 апреля 2011

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

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 голосов
/ 14 апреля 2011

Вы ищете Компилятор Firewall , a.k.a. PIMPL?

1 голос
/ 12 сентября 2013

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

...