【发布时间】:2015-05-01 10:09:42
【问题描述】:
对于演示该问题所需的大量代码,我深表歉意。我在使用带有 std::unique_ptr 的 pimpl 习惯用法时遇到问题。具体来说,当一个类(具有 pimpl'ed 实现)用作另一个具有 pimpl'ed 实现的复合类中的成员数据时,似乎会出现问题。
我能找到的大多数答案都与缺少 explicit destructor declaration 相关,但正如您在此处看到的,我已经声明并定义了析构函数。
这段代码有什么问题,能不能在不改变设计的情况下修改编译?
注意:错误似乎发生在 SomeComposite::getValue() 的定义中,并且编译器直到编译时才能看到错误。在 memory.h 中遇到错误,消息是 Invalid application of 'sizeof' to an Complete type '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();
}
}
【问题讨论】:
-
对于在不使用
= default构造函数的情况下发生这种神秘错误的情况,我的解决方案是在我的类中包含一个显式析构函数。
标签: c++ c++11 unique-ptr pimpl-idiom incomplete-type