简体   繁体   中英

Why does this call the copy constructor, not the move constructor?

I have a class, 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())
{
}

and a class, PlayerMoveComponen t, that contains a PlayerInputComponent member and initializes it using a std::unique_ptr passed as a parameter. 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. In this case though I know that the reference will remain in scope for duration of the PlayerInputComponent object's lifetime.

Since I'm initializing the PlayerMoveComponent 's inputComponent variable from a temporary, I believe one of the following two things is supposed to happen:

  1. PlayerInputComponent 's move constructor is used to initialize the playerInputComponent member variable.
  2. The move is elided by the compiler.

However, Visual Studio 2012 spits this out:

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?

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?

If you initialize a new Object using = , the copy constructor will be triggered by default. To trigger the move constructor, you need to alter the behavior of operator= You can find an example here Hope I helped you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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