I would like to ask you to verify the following implementation of the PIMPL idiom. In this dummy implementation the stream is read into a string.
X.h
#ifndef X_H
#define X_H
#include <memory>
#include <istream>
namespace mynamespace
{
class X
{
class XImplementation;
std::unique_ptr<XImplementation> _implementation;
X();
void swap(X& other);
public:
X(std::istream& stream);
X(const X& copyFrom);
X& operator=(const X& copyFrom);
X(X&& moveFrom);
X& operator=(X&& moveFrom);
~X();
std::string get_info();
}
}
#endif // X_H
X.cpp
#include "X.h"
using namespace mynamespace;
class X::XImplementation
{
std::string _contents;
public:
XImplementation(std::istream& stream)
: _contents(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>()) { }
std::string get_info()
{
return _contents;
}
};
X::X() = default;
void X::swap(X& other)
{
std::swap(_implementation, other._implementation);
}
X::X(std::istream& stream) : _implementation(new X::XImplementation(stream)) { }
X::X(const X& copyFrom) : _implementation(new XImplementation(*copyFrom._implementation)) { };
X& X::operator=(const X& copyFrom)
{
X temp(copyFrom);
swap(temp);
return *this;
}
X::X(X&& moveFrom)
{
swap(moveFrom);
}
X& X::operator=(X&& moveFrom)
{
swap(moveFrom);
return *this;
}
X::~X() = default;
std::string X::get_info()
{
return _implementation->get_info();
}
I tried my best to use copy-and-swap idiom to implement all the constructors. I wanted to make sure that X can be passed by value correctly. I am mostly wandering about this part, because I used a private method to implement the swap and here a public friend function is suggested.
I will appreciate any suggestions and critiques.
mynamespace::X
doesn't look like real code from a project you wrote or maintain, so isn't within scope for Code Review. See help centre. \$\endgroup\$get_info
method. Am I wrong? \$\endgroup\$get_info()
sure. \$\endgroup\$