标签:incomplete-type pimpl-idiom c c11 unique-ptr
我为证明问题所需的大量代码道歉.我在使用带有std :: unique_ptr的pimpl习惯用法时遇到了问题.具体地说,当一个类(具有pimpl’ed实现)被用作具有pimpl’ed实现的另一个复合类中的成员数据时,似乎会出现问题.
我能找到的大多数答案都缺少explicit destructor declaration,但正如你在这里看到的,我已经声明并定义了析构函数.
这段代码有什么问题,可以修改它来编译而不改变设计吗?
注意:错误似乎发生在SomeComposite :: getValue()的定义中,并且编译器在编译时才能看到错误.在memory.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();
}
}
解决方法:
你不能使用带有Pimpl类的头文件中声明的默认构造函数和赋值运算符(例如SomeInt(SomeInt&& other)= default;),因为默认实现是内联的,并且在声明SomeInt的声明SomeInt时: :impl不完整,所以unique_ptr抱怨.您必须自己声明和定义所有特殊成员函数(例如,在实现文件中).
也就是说,更改SomeInt和SomeComposite声明如下:
// SomeInt.h
SomeInt( SomeInt&& other ); // move
SomeInt& operator=( SomeInt&& other ); // move assign
// SomeInt.cpp
// after definition of SomeInt::impl
SomeInt::SomeInt( SomeInt&& other ) = default;
SomeInt& operator=( SomeInt&& other ) = default;
另一个选择是按照this answer中的建议创建自己的Pimpl指针.
标签:incomplete-type,pimpl-idiom,c,c11,unique-ptr 来源: https://codeday.me/bug/20190824/1711421.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。