Я пытаюсь понять идиому PIMPL.
У меня есть несколько файлов, скажем, "Implement.cpp / Implement.h", реализующих идиому PIMPL: он содержит интерфейс publi c и частную реализацию .
"Client.cpp / Client.h" использует интерфейс publi c.
Другой файл "main. cpp" просто использует класс клиента.
Я написал очень простой make-файл. Сначала все компилируется:
g++ -std=c++11 -c main.cpp
g++ -std=c++11 -c Implementation.cpp
g++ -std=c++11 -c Client.cpp
g++ -o main main.o Implementation.o Client.o -std=c++11
Я хотел бы сказать, что, если я изменю что-то в реализации PIMPL, клиент не будет перекомпилировать, и что, если я не буду использовать идиому PIMPL (Если я модификация в интерфейсе publi c), клиент перекомпилирует.
Вывод компилятора при изменении частной реализации:
g ++ -std = c ++ 11 - c Реализация. cpp
g ++ -o main main.o Реализация.o Client.o -std = c ++ 11
Вывод компилятора при публикации интерфейса c (новый метод, новый элемент с инициализацией и т. д. c) изменено:
g ++ -std = c ++ 11 - c Реализация. cpp
g ++ -o main main.o Реализация.o Client.o -std = c ++ 11
На самом деле, это то же самое.
Я ожидал, что если я изменю что-то в интерфейсе publi c, он должен перекомпилировать и "Реализация", и "Клиент" :
g++ -std=c++11 -c Implementation.cpp
g++ -std=c++11 -c Client.cpp
g++ -o main main.o Implementation.o Client.o -std=c++11
Что на самом деле делает компилятор, и как я могу убедиться, что компилятор компилирует только необходимое при использовании идиомы PIMPL?
EDIT (код добавлен):
Реализация. cpp:
#include "Implementation.h"
class PublicInterface::PrivateImplementation
{
public:
PrivateImplementation(std::string name) : name(name), id(0){};
virtual ~PrivateImplementation(void){};
std::string name;
int id;
};
PublicInterface::PublicInterface(std::string name) : pImplPrivate(new PrivateImplementation(name)){}
PublicInterface::~PublicInterface() = default;
int PublicInterface::GetID(void) const { return this->pImplPrivate->id;}
void PublicInterface::SetID(const int id) { this->pImplPrivate->id = id;}
Реализация.h:
#include <memory>
#include <string>
class PublicInterface
{
public:
PublicInterface(std::string name);
virtual ~PublicInterface(void);
int GetID(void) const;
void SetID(const int id);
private:
class PrivateImplementation;
std::unique_ptr<PrivateImplementation> pImplPrivate;
};
client. cpp:
#include <iostream>
#include "Client.h"
#include "Implementation.h"
Client::Client(void){}
Client::~Client(void){}
void Client::Caller(void)
{
PublicInterface interface(std::string("Interface"));
std::cout << "Interface ID " << interface.GetID() << std::endl;
interface.SetID(5);
std::cout << "Interface ID " << interface.GetID() << std::endl;
}
client. h:
class Client
{
Client(void);
virtual ~Client(void);
public:
static void Caller(void);
static void Another(void);
};
main. cpp:
#include "Client.h"
int main(int argc, char** argv)
{
Client::Caller();
return 0;
}
Makefile:
CPPFLAGS=-std=c++11
main : main.o Implementation.o Client.o
g++ -o main main.o Implementation.o Client.o $(CPPFLAGS)
main.o : main.cpp
g++ $(CPPFLAGS) -c main.cpp
Implementation.o : Implementation.cpp
g++ $(CPPFLAGS) -c Implementation.cpp
Client.o : Client.cpp
g++ $(CPPFLAGS) -c Client.cpp
clean :
rm main main.o Implementation.o Client.o