简体   繁体   English

为什么这会调用复制构造函数,而不是移动构造函数?

[英]Why does this call the copy constructor, not the move constructor?

I have a class, PlayerInputComponent : 我有一个类, PlayerInputComponent

.h: 。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: 的.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())
{
}

and a class, PlayerMoveComponen t, that contains a PlayerInputComponent member and initializes it using a std::unique_ptr passed as a parameter. 和一个类PlayerMoveComponen t,它包含一个PlayerInputComponent成员,并使用作为参数传递的std::unique_ptr对其进行初始化。 Its constructor: 它的构造函数:

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

I defined my own move constructor for the PlayerInputComponent class since my understanding is that a default move constructor won't be constructed for a class which contains a reference member. 我为PlayerInputComponent类定义了自己的移动构造函数,因为我的理解是不会为包含引用成员的类构造默认移动构造函数。 In this case though I know that the reference will remain in scope for duration of the PlayerInputComponent object's lifetime. 在这种情况下,虽然我知道引用将保留在PlayerInputComponent对象的生存期的持续时间范围内。

Since I'm initializing the PlayerMoveComponent 's inputComponent variable from a temporary, I believe one of the following two things is supposed to happen: 由于我是从临时初始化PlayerMoveComponentinputComponent变量,我相信应该发生以下两件事之一:

  1. PlayerInputComponent 's move constructor is used to initialize the playerInputComponent member variable. PlayerInputComponent的移动构造函数用于初始化playerInputComponent成员变量。
  2. The move is elided by the compiler. 编译器省略了此举。

However, Visual Studio 2012 spits this out: 但是,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 &)'

Why is the copy constructor being called here? 为什么在这里调用复制构造函数? Making the PlayerInputComponent class's parentMoveComponent member a regular ParentMoveComponent instance, rather than a reference, gets rid of the error, but I don't understand why - I've tested and verified that move constructing objects with reference members works so long as you provide your own move constructor, so what's the deal? 使PlayerInputComponent类的parentMoveComponent成员成为一个常规的ParentMoveComponent实例,而不是一个引用,摆脱了错误,但我不明白为什么 - 我已经测试并验证,只要你提供你的参考成员就可以移动构建对象自己的移动构造函数,那么交易是什么?

I'm sorry in advance if this doesn't really answer your question, I just want to react on the apparent complexity of your problem. 如果这不能真正回答你的问题,我很抱歉,我只是想对你问题的明显复杂性做出反应。 If I may, wouldn't this be a thousand times simpler: 如果可以的话,这不会简单一千倍:

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

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);
}

and yet achieve the same thing? 并实现同样的目标? I have nothing against using the new features in c++11, like std::unique_ptr , but IMHO, ensuring that a pointer can never be dereferenced from two places should not be a matter of run-time checking (except maybe in very rare cases), but a matter of design.. shouldn't it? 我没有反对使用c ++ 11中的新功能,比如std::unique_ptr ,但恕我直言,确保指针永远不能从两个地方取消引用不应该是运行时检查的问题(除非非常罕见)案例),但设计问题..不应该吗?

If you initialize a new Object using = , the copy constructor will be triggered by default. 如果使用=初始化新Object,则默认情况下将触发复制构造函数。 To trigger the move constructor, you need to alter the behavior of operator= You can find an example here Hope I helped you. 要触发移动构造函数,您需要更改operator=的行为。您可以在此处找到示例希望我帮助过您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM