gpt4 book ai didi

使用 std::unique_ptr 的 C++ Pimpl Idiom 不完整类型

转载 作者:太空狗 更新时间:2023-10-29 20:24:17 24 4
gpt4 key购买 nike

对于演示该问题所需的大量代码,我深表歉意。我在将 pimpl idiom 与 std::unique_ptr 一起使用时遇到问题。具体来说,当一个类(具有 pimpl 的实现)在另一个具有 pimpl 的实现的复合类中用作成员数据时,问题似乎会发生。

我能找到的大部分答案都解决了缺少 explicit destructor declaration 的问题,但是正如您在这里看到的,我已经声明并定义了析构函数。

这段代码有什么问题,是否可以在不改变设计的情况下修改编译?

注意:错误似乎出现在 SomeComposite::getValue() 的定义中,编译器直到编译时才能发现错误。在 memory.h 中遇到错误,消息是 Invalid application of 'sizeof' to an incomplete 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();
}
}

最佳答案

您不能使用在 Pimpl 类的头文件中声明的默认构造函数和赋值运算符(例如 SomeInt( SomeInt&& other ) = default;),因为默认实现是内联的,并且在声明点 SomeInt 的声明 SomeInt::impl 不完整,所以 unique_ptr 提示。您必须自行声明和定义所有特殊成员函数(即在实现文件中)。

即改变SomeIntSomeComposite声明如下:

// 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;

另一种选择是创建您自己的 Pimpl 指针,如 this answer 中所建议的那样.

关于使用 std::unique_ptr 的 C++ Pimpl Idiom 不完整类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28786387/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com