2

I want to initialize Enemy::copy using the parameter passed to the initialization constructor, but I get the following error:

C2280: 'Enemy &Enemy::operator =(const Enemy &)': attempting to reference a deleted function

Here is the declaration of class Enemy:

 #include "Pickup.h"
 class Enemy : public Entity
 {
 private:
        std::vector<Pickup>& copy;
 public:
        Enemy::Enemy(std::vector<Pickup>& arraypickup) : copy(arraypickup) {} 
 };

And the code from main():

std::vector<Pickup> arraypickup;
Enemy enemy(arraypickup);

How do I solve it?

iksemyonov
  • 4,106
  • 1
  • 22
  • 42
Melchior_
  • 75
  • 2
  • 10
  • 1
    The two lines from `main` that you showed do not cause the error you posted. It is complaining about a deleted copy constructor. None of your code uses copy construction. The error is elsewhere. – Cory Kramer Feb 06 '16 at 21:29
  • probably `enemy` is passed by value later on – M.M Feb 06 '16 at 21:35
  • Later nothing happens with copy, so i don't know whats wrong ;/ – Melchior_ Feb 06 '16 at 21:43
  • Melchior, you are referring to the `Enemy::copy`. CoryKramer is referring to the copy constructor function in the Enemy class. You chose a really unfortunate name for that field. – iksemyonov Feb 06 '16 at 21:46
  • 1
    The problem is most likely your oddly named member `copy`, which is not a copy of anything, but a reference to whatever you pass to the constructor. References are not re-assignable, so the compiler cannot implicitly define a copy assignment operator for your class. So if you try to copy assign something to `Enemy`, you'll see that error. – Praetorian Feb 06 '16 at 22:04
  • Praetorian, you were right, I have replicated the case. May I post an answer based on your idea and my code? – iksemyonov Feb 06 '16 at 22:13
  • @iksemyonov Yes, of course. (you should use @ so people get notified) – Praetorian Feb 06 '16 at 22:20
  • @Melchior_, has the fix resolved the issue? – iksemyonov Feb 08 '16 at 00:55

1 Answers1

2

This answer is based on the correct suggestion by @Praetorian.

Short answer with a fix:

The issue is in the std::vector<Pickup>& copy; member of the Enemy class. Change that to std::vector<Pickup> copy;, removing the reference, to fix the error. Indeed, there is absolutely no need to store the vector as a reference, on the contrary, as you can see, having reference members in a class cause errors like the one you've faced. You may have been confused by the fact that the vector is passed by reference to the initialization c'tor, but it in no way means that you should also make the class member a reference.

If you still want to store the Enemy::copy data by reference, for e.g. performance issues, consider making it a pointer, like so:

class Enemy : public Entity
 {
 private:
        std::vector<Pickup>* copy;
 // rest of the class...
 };

Long answer:

Code to reproduce the issue:

class Foo
{
    int& ri;
public:
//    default c'tor can't be defined in a sane fashion  because of the reference member ri
//    Foo() : ri(0) {}
    Foo(int& _ri) : ri(_ri) {}
};

int main(int argc, char **argv)
{
    int i{42};
    Foo f1{i};
    Foo f2{f1}; // we don't have a default constructor so using auto-generated copy c'tor
    f2 = f1; // <--- error
    return 0;
}

Results in the error:

main.cpp: In function 'int main(int, char**)':
main.cpp:14:12: error: use of deleted function 'Foo& Foo::operator=(const Foo&)'
         f2 = f1; // <--- error
            ^
main.cpp:1:11: note: 'Foo& Foo::operator=(const Foo&)' is implicitly deleted
                     because the default definition would be ill-formed:
     class Foo
           ^
main.cpp:1:11: error: non-static reference member 'int& Foo::ri',
                      can't use default assignment operator

Explanation:

An auto-generated operator=(), which would otherwise be generated in this case [1], is considered to be ill-formed due to the fact the you can't reassign references in C++ [2]. The auto-generated operator=(Foo& other), should it exist, would attempt to perform this->ri = other.ri, which is considered to be incorrect ("ill-formed", as reported by the compiler), since it's a re-assignment of the reference ri.

Finally, I suggest to see [3], with an in-depth answer on the issue.

  1. about auto-generated copy assignment operator

  2. about re-assigning references

  3. Assignment operator and copy constructor in the presence of references

Community
  • 1
  • 1
iksemyonov
  • 4,106
  • 1
  • 22
  • 42