9

我有一堂课PlayerInputComponent

。H:

class PlayerInputComponent
{
public:
    PlayerInputComponent(PlayerMoveComponent& parentMoveComponent_, std::unique_ptr<IRawInputConverter> inputConverter_);
    PlayerInputComponent(PlayerInputComponent&& moveFrom);
    void update();

private:
    std::unique_ptr<IRawInputConverter> inputConverter;
    PlayerMoveComponent& parentMoveComponent;
};
}

.cpp:

PlayerInputComponent::PlayerInputComponent(PlayerMoveComponent& parentMoveComponent_, std::unique_ptr<IRawInputConverter> inputConverter_) :
    parentMoveComponent(parentMoveComponent_),
    inputConverter(std::move(inputConverter_))
{
}

PlayerInputComponent::PlayerInputComponent(PlayerInputComponent&& moveFrom) :
    parentMoveComponent(moveFrom.parentMoveComponent),
    inputConverter(moveFrom.inputConverter.release())
{
}

和一个类PlayerMoveComponent,它包含一个PlayerInputComponent成员并使用std::unique_ptr作为参数传递的 a 对其进行初始化。它的构造函数:

PlayerMoveComponent::PlayerMoveComponent(/* other parameters */ std::unique_ptr<IRawInputConverter> inputConverter) :
    //other initializations
    inputComponent(PlayerInputComponent(*this, std::move(inputConverter)))
{
}

我为该类定义了自己的移动构造函数,PlayerInputComponent因为我的理解是不会为包含引用成员的类构造默认移动构造函数。在这种情况下,虽然我知道引用将在PlayerInputComponent对象的生命周期内保持在范围内。

由于我正在从临时初始化PlayerMoveComponent'sinputComponent变量,因此我相信应该发生以下两件事之一:

  1. PlayerInputComponent的移动构造函数用于初始化playerInputComponent成员变量。
  2. 编译器忽略了这一举动。

然而,Visual Studio 2012 吐出了这个:

error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
1>          with
1>          [
1>              _Ty=SDLGame::IRawInputConverter
1>          ]
1>          c:\program files\microsoft visual studio 11.0\vc\include\memory(1447) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr'
1>          with
1>          [
1>              _Ty=SDLGame::IRawInputConverter
1>          ]
1>          This diagnostic occurred in the compiler generated function 'PlayerInputComponent::PlayerInputComponent(const PlayerInputComponent &)'

为什么在这里调用复制构造函数?使PlayerInputComponent类的parentMoveComponent成员成为常规ParentMoveComponent实例而不是引用可以消除错误,但我不明白为什么-我已经测试并验证了只要您提供自己的移动构造函数,使用引用成员构建对象的移动就可以工作,那么有什么关系呢?

4

2 回答 2

1

如果这不能真正回答您的问题,我很抱歉,我只是想对您问题的明显复杂性做出反应。如果可以的话,这不是简单一千倍吗:

/********************     **********     ********************/

class C {};
class B;



class A
{
public:

    A(): _b(nullptr), _c(nullptr) {}
    A( B *b, C *c ): _b(b), _c(c) {}
    A( A&& a ): _b(a._b), _c(a._c) {}

private:

    C *_c;
    B *_b;
};



class B
{
public:

    B( /* other parameters */ C *c ): _a( A(this,c) ) {}

private:

    A _a;
};


    /********************     **********     ********************/


int main()
{
    C c;
    B b(&c);
}

却实现同样的目标?我不反对使用 c++11 中的新功能,例如std::unique_ptr,但是恕我直言,确保永远不能从两个地方取消引用指针不应该是运行时检查的问题(可能在极少数情况下除外),但是设计问题..不应该吗?

于 2013-05-07T09:47:58.363 回答
1

如果使用 初始化新对象=,则默认情况下将触发复制构造函数。要触发移动构造函数,您需要更改的行为您可以在此处operator= 找到示例 希望对您有所帮助。

于 2017-04-15T12:55:01.603 回答