Reputation: 201
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:
PlayerInputComponent
's move constructor is used to initialize the playerInputComponent
member variable.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?
Upvotes: 9
Views: 1223
Reputation: 1619
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.
Upvotes: 2
Reputation: 7962
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?
Upvotes: 1