Reputation: 43
Using the following code :
#include <iostream>
class A
{
public:
A(int truc) : truc(truc) {}
A(const A & other) = delete;
private:
int truc;
};
class B
{
public:
B(int machin, A a) : machin(machin), a(a) {}
private:
int machin;
A a;
};
int main()
{
A a(10);
B b(2,a);
return 0;
}
I get a compile error "error: use of deleted function 'A::A(const A&)"
How can I circonvent this problem if I still want the class A not to be able to be copied ?
Upvotes: 3
Views: 105
Reputation: 7868
Taking A
by value in B::B(int machin, A a)
is the main issue, do B::B(int machin, A& a)
or B::B(int machin, const A& a)
.
The same applies to the assignment to the field within the constructor body. The field declaration in class B
should hence be A& a;
or const A& a;
, respectively.
However, you probably also want to delete the assignment operator: A& operator=( const A& ) = delete;
Take a look at boost non-copyable.
Its implementation also depends on whether C++11 is available: http://www.boost.org/doc/libs/1_60_0/boost/core/noncopyable.hpp
Upvotes: 2
Reputation: 2007
B
's constructor takes object of type A
by value -> creates new object (copy)
B(...,A a) ...
^^^^ pass by value
Passing by reference won't create a new object (copy).
B(...,A &a)...
^^^^^ pass by reference -> no copy
Also, this means that you can't store it in B
as object A a
, because that would, again, create new object (copy), you'll have to store it as reference.
This could cause some problems:
B* createNewObject()
{
A a(...); //local object is created
B* ptr = new B(...,a); // reference in B now refers to local object
}// However, here is local object destroyed, so reference in B is now invalid (dangling reference)
int main()
{
B *pb = createNewObject();
//Any operation on B working with that invalid reference causes UNDEFINED BEHAVIOUR
}
Additionaly, bear in mind that any change in a
will also change object you passed (because that reference refers to same object you passed).
Upvotes: 1
Reputation: 180303
Considering the alternative to copying is moving, you want:
B(int machin, A&& a) : machin(machin), a(a) {}
That correctly disallows A a(10); B b(2,a);
which is a copy of a
. You'd now need std::move(a)
there.
Upvotes: 1