-4

I am trying to create a class that never duplicates as it has a LOT of data inside of its fields. To do this I defined the class like this:

class Foo {
public:
   Foo(int i);
   Foo();
   Foo(const Foo&) = delete;
}

This causes a compiler error if I tried to do something like:

Foo a(2);
Foo b = a;

However for whatever reason this does not cover this scenario where data is copied.

Foo* array;
array = new Foo[10000];
Foo a(2);
array[1] = a;

Why is this?

J.Doe
  • 1,502
  • 13
  • 47
  • 7
    `Foo a();` is a function declaration. – Jesper Juhl Sep 13 '18 at 17:46
  • 1
    `Foo a();` - compiler error resulting from here would have nothing to do with copy constructor - that does not define a `Foo` object, it declares a function. –  Sep 13 '18 at 17:47
  • In this example, `Foo` has no constructors at all. Declaring a constructor, even to delete it, prevents the default constructor from being generated. You would need to declare the default constructor. – François Andrieux Sep 13 '18 at 17:48
  • **−1** Especially the last example is clearly **not real code**. Also voted to close as lacking a reproducible example. – Cheers and hth. - Alf Sep 13 '18 at 17:49
  • Updated the question with a constructor and some small edits. Hopefully this is less psuedocodey for y'all. – J.Doe Sep 13 '18 at 17:51
  • 1
    What about the `compiler error` you receive? – Dalton Cézane Sep 13 '18 at 17:52
  • 1
    @J.Doe, unfortunately, you can't use `array = new Foo[10000];` unless you have a default constructor. – R Sahu Sep 13 '18 at 17:52
  • Gotcha. Updated question again. I didnt feel the need to include more than necessary code for Foo but I can see the confusion it causes so added a default constructor. Believe it or not the class I am writing is not named Foo. – J.Doe Sep 13 '18 at 17:53
  • Time to review the basics of constructors including definition & when they are called. – philipxy Sep 13 '18 at 18:10

1 Answers1

7

First of all,

Foo a();

does not create an object of type Foo. It declares a function that takes no arguments and returns a Foo.

Assuming that you have an object of type Foo,

Foo b = a;

calls the copy constructor to initialize b. However, when you use

array[1] = a;

it does not use the copy constructor. It is an assignment operation. deleteing the copy constructor does not delete the copy assignment operator. Hence, the last line is not an error.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • There is still the problem that `Foo` is not default constructible. – François Andrieux Sep 13 '18 at 17:49
  • Ah so assignment does not cause any new memory to be used? Simple two locations pointing at the same object? – J.Doe Sep 13 '18 at 17:52
  • @J.Doe, there are two different objects. The value of one object is assgined to the other object. – R Sahu Sep 13 '18 at 17:53
  • That makes sense! – J.Doe Sep 13 '18 at 17:54
  • @J.Doe Assignment won't involve the copy constructor, but rather the assignment operator overload. – πάντα ῥεῖ Sep 13 '18 at 17:54
  • That said, one of the simplest ways to implement the assignment operator uses the copy constructor. [See the Copy and Swap Idiom.](https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom) Note that while it is simple and bulletproof, Copy and Swap can be expensive. – user4581301 Sep 13 '18 at 18:08