Приносим извинения за большой объем кода, необходимый для демонстрации проблемы. У меня проблема с использованием идиомы pimpl с std :: unique_ptr. В частности, проблема возникает, когда один класс (который имеет реализацию pimpl'ed) используется как данные элемента в другом составном классе с реализацией pimpl'ed.C++ Pimpl Idiom Неполный тип с использованием std :: unique_ptr
Большинство ответов я смог найти дело с отсутствием explicit destructor declaration, но, как вы можете видеть здесь, я объявил и определил деструкторы.
Что не так с этим кодом, и может ли он быть изменен для компиляции без изменения дизайна?
Примечание: ошибка возникает в определении SomeComposite :: getValue() и что компилятор не может видеть ошибку до момента компиляции. Ошибка встречается в памяти.h, и сообщение Недопустимое применение параметра sizeof для неполного типа pimplproblem :: SomeInt :: impl '.
SomeInt.h
#pragma once
#include <iostream>
#include <memory>
namespace pimplproblem
{
class SomeInt
{
public:
explicit SomeInt(int value);
SomeInt(const SomeInt& other); // copy
SomeInt(SomeInt&& other) = default; // move
virtual ~SomeInt();
SomeInt& operator=(const SomeInt& other); // assign
SomeInt& operator=(SomeInt&& other) = default; // move assign
int getValue() const;
private:
class impl;
std::unique_ptr<impl> myImpl;
};
}
SomeInt.cpp
#include "SomeInt.h"
namespace pimplproblem
{
class SomeInt::impl
{
public:
impl(int value)
:myValue(value)
{}
int getValue() const
{
return myValue;
}
private:
int myValue;
};
SomeInt::SomeInt(int value)
:myImpl(new impl(value))
{}
SomeInt::SomeInt(const SomeInt& other)
:myImpl(new impl(other.getValue()))
{}
SomeInt::~SomeInt()
{}
SomeInt& SomeInt::operator=(const SomeInt& other)
{
myImpl = std::unique_ptr<impl>(new impl(other.getValue()));
return *this;
}
int SomeInt::getValue() const
{
return myImpl->getValue();
}
}
SomeComposite.h
#pragma once
#include <iostream>
#include <memory>
#include "SomeInt.h"
namespace pimplproblem
{
class SomeComposite
{
public:
explicit SomeComposite(const SomeInt& value);
SomeComposite(const SomeComposite& other); // copy
SomeComposite(SomeComposite&& other) = default; // move
virtual ~SomeComposite();
SomeComposite& operator=(const SomeComposite& other); // assign
SomeComposite& operator=(SomeComposite&& other) = default; // move assign
SomeInt getValue() const;
private:
class impl;
std::unique_ptr<impl> myImpl;
};
}
SomeComposite.cpp
#include "SomeComposite.h"
namespace pimplproblem
{
class SomeComposite::impl
{
public:
impl(const SomeInt& value)
:myValue(value)
{}
SomeInt getValue() const
{
return myValue;
}
private:
SomeInt myValue;
};
SomeComposite::SomeComposite(const SomeInt& value)
:myImpl(new impl(value))
{}
SomeComposite::SomeComposite(const SomeComposite& other)
:myImpl(new impl(other.getValue()))
{}
SomeComposite::~SomeComposite()
{}
SomeComposite& SomeComposite::operator=(const SomeComposite& other)
{
myImpl = std::unique_ptr<impl>(new impl(other.getValue()));
return *this;
}
SomeInt SomeComposite::getValue() const
{
return myImpl->getValue();
}
}
см. Также http://stackoverflow.com/q/8595471/103167 –