我有一個類的設定,我已經轉換為使用pimpl,類似于這樣:
(outline only, I'm aware this doesn't compile)
struct GAME
{
unique_ptr<GAME_IMPL> _impl;
explicit GAME() : _impl( new GAME_IMPL( *this ) ) ;
IMAGES getImages() { return _impl._images; }; ; return _impl._images
};
結構 GAME_IMPL
{
IMAGES _images;
PLAYER _player。
explicit GAME_IMPL( GAME& game ) : _player( game ) { };;;。
};
結構 PLAYER
{
SPRITE _sprite;
explicit PLAYER( GAME& game ) { _sprite. load( game.getImages() ); }; _sprite.
};
在我轉換為pimpl模式之前,這很好。
_sprite.load( game.getImages() )可以訪問GAME::_images,因為GAME::_images在GAME::_player之前實體化了。
然而,在轉換為pimpl后,你可以看到_sprite.load( game. getImages() )將會失敗 - PLAYER不能訪問GAME::_images,因為GAME::getImages使用了GAME::_impl,它在所有的GAME_IMPL被構建后才被分配。
顯然,我的例子是被設計出來的。但是有沒有什么方法可以讓_impl指標在GAME_IMPL物件被構建之前或之后被設定呢?
我考慮了以下幾點:
- 只傳遞
PLAYER的必要元素。這是很混亂的,因為它涉及到每次我調整PLAYER::PLAYER的欄位時都要修改PLAYER的API。而且在實踐中,PLAYER的建構式可能最終要接受30個奇怪的引數。 - 使用兩階段的初始化,例如
PLAYER::PLAYER(),PLAYER::Load()- 這甚至更加混亂,因為它意味著將參考轉換為指標。 - 傳遞
PLAYERGAME_IMPL- 這失去了首先使用pimpl的任何好處。
uj5u.com熱心網友回復:
我想你錯過了一些細節,這里有一個可以編譯的設定。
#include < memory>
結構 GAME_IMPL。
struct IMAGES {};
//A 'trick' I often use[/span].
//對于pimpl,你可以定義一個抽象的基礎。
//幫助你檢查是否有public和impl類。
///實作同樣的功能。
//
///它還能確保你只有一個指向介面的指標。
//span>你的公共頭檔案中的實作。
結構 游戲_ITF
{
virtual ~GAME_ITF() = default;
virtual IMAGES get_Images()= 0;
protected:
GAME_ITF() = default; // prevent accidental instantiation..
};
//在pimpl中,游戲只是轉發到game_impl。
struct GAME : public GAME_ITF
{
std::unique_ptr<GAME_ITF> _impl;
GAME()。
virtual ~GAME() = default;
IMAGES get_Images() override
{
return _impl->get_Images()。
}
};
結構 SPRITE
{
void load(IMAGES) { /*.}
};
結構 PLAYER
{
SPRITE _sprite;
explicit PLAYER(GAME_ITF& game)
{
_sprite.load(game.get_Images() 。)
}
};
struct GAME_IMPL : public GAME_ITF
{
IMAGES _images;
PLAYER _player。
GAME_IMPL() :
_player{*this}。// <===player可以參考實作的介面(也不需要植入細節)。
{
}
IMAGES get_Images() override
{
return IMAGES{};
}
};
GAME::GAME() :
_impl(std::make_unique<GAME_IMPL> ())
{
}
int main()
{
GAME游戲。
IMAGES images = game.get_Images()。
uj5u.com熱心網友回復:
P Kramer的答案是對我的案例中提出的問題的好答案。
然而,如果有人通過谷歌搜索"傳遞部分構造的物件"而最終來到這里,我確實發現這是可行的。基本上,嵌套類(本例中為GAME_IMPL)必須在父類(本例中為GAME)中分配自己的指標,即:
explicit GAME_IMPL( GAME& game ) : _player( (game. _impl.reset( this ), game) ) { }
現在GAME::_impl在PLAYER::PLAYER期間被分配,GAME::getImages()可以被使用。
這對于pimpl的情況來說是很混亂的,但可能會解決類似的問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/321883.html
標籤:
