user65490
user65490

Reputation: 43

disabling copy constructor in c++ and use of an Object

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

Answers (3)

Sam
Sam

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

PcAF
PcAF

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

MSalters
MSalters

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

Related Questions