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?
Move constructor moves the resources in the heap, i.e., unlike copy constructors which copy the data of the existing object and assigning it to the new object move constructor just makes the pointer of the declared object to point to the data of temporary object and nulls out the pointer of the temporary objects.
The reason the copy constructor is not called is because the copy constructor itself is a function with one parameter. You didn't call such function,so it didn't execute.
When we create our own copy constructor, we pass an object by reference and we generally pass it as a const reference. One reason for passing const reference is, we should use const in C++ wherever possible so that objects are not accidentally modified.
The answer is No. The creation of the object memory is done via the new instruction. Copy constructor is then in charge of the actual copying (relevant only when it's not a shallow copy, obviously). You can, if you want, explicitly call a different constructor prior to the copy constructor execution.
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.
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 love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With