-3

I didn't overload the (=) operator but still it runs fine in codeblocks. however when I ran this code on C++ shell it compiled successfully however the output was blank. Can somebody please explain why is it running fine in codeblocks even though I didn't write the code for the copy assignment?

Also another question...

If on line 1 I change the return type to string instead of string& it displays an error (about temporary variable) but if I change the code of line 2 to dummy(dummy& abc : ptr(new string (abc.print())) the program runs fine (despite the return type of line 1 being string). Why is it so?

class dummy {
  string* ptr;

 public:
  dummy(string ab) {
    ptr = new string;
    ptr = &ab;
  }
  ~dummy() { delete ptr; }
  string& print() { return *ptr; }  // line1
  dummy(dummy& abc) {
    ptr = new string;
    ptr = &(abc.print());
  }  // line2
  dummy(){};
};

int main() {
  dummy x("manzar");
  dummy y;
  y = x;

  cout << x.print();
  cout << "\n" << y.print();
}

I didn't expect it to run fine however it is working fine. It is copying the content from x to y.

ejderuby
  • 710
  • 5
  • 21
  • Look at Howard Hinnants table of compiler genarated special members : https://stackoverflow.com/questions/24342941/what-are-the-rules-for-automatic-generation-of-move-operations – engf-010 Aug 02 '19 at 17:30
  • 1
    Remember that the compiler is *not* required to warn you or error out when you do something stupid, nor when you do something that breaks language rules and lands you in undefined behaviour land, etc. The compiler is *only* required (in general) to stop you when your code has a syntax error and cannot be parsed. Anything that you do wrong beyond that is on *you* and the compiler is *not* required to help you. Nor is it required to tell you when it takes advantage of your error to produce garbage. It's *your responsibility* to know *all* the language rules and abide by them. – Jesper Juhl Aug 02 '19 at 17:37
  • The compiler will (according to the language rules), synthesize certain member functions for you with default behaviour unless you implement them yourself or explicitly `= delete` them. – Jesper Juhl Aug 02 '19 at 17:40
  • Just because something compiles and runs, in *no way* means that it is *correct*. – Jesper Juhl Aug 02 '19 at 17:41
  • 1
    _"My program runs fine"_ I have a hard time believing this. You're doing some awfully funny things with pointers, and your code will leak memory like a sieve and will eagerly doubly-delete things. You would benefit from reading a [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – alter_igel Aug 02 '19 at 17:42
  • `ptr = new string; ptr = &(abc.print());` - Why would you *do* that. That's just plain *wrong*. – Jesper Juhl Aug 02 '19 at 17:45
  • You have asked multiple questions in a single question. Please don't do that as the result tends to be an incomprehensible mess of no value to others. Pick one question, preferably one that is not answered by [What is The Rule of Three?](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). – JaMiT Aug 02 '19 at 19:19
  • well,thank you for your help.i didn't knew that i was commiting so many mistakes.i am new to coding.i am learning c++ from cplusplus.com/doc/tutorial.but i am having a hard time understanding oops concepts.can somebody suggest some good material that could help me. – El Professor Aug 02 '19 at 19:57

2 Answers2

2

The code compiles as the compiler automatically generates an assignment operator for you. See https://en.cppreference.com/w/cpp/language/copy_assignment for the full rules of when this does and doesn't happen. See also What is The Rule of Three?

The reason your code doesn't work on cpp shell is probably due to various undefined behaviour including (but possibly not limited to):

  1. Violating the rule of three: What is The Rule of Three?
  2. Your dummy(string ab) constructor stores a pointer to a temporary variable. ptr = &ab; should be *ptr = ab;
  3. Your dummy(dummy& abc) copy constructor should be dummy(const dummy& abc) and again ptr = &(abc.print()); should be *ptr = abc.print();
  4. Your default constructor dummy() should initialise ptr to nullptr
  5. print() should check that ptr is not null.
Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
2

It is part of the specification of C++ that by default the compiler will generate a default copy assignment operator if no user-defined copy assignment operators are included in the class definition. There are several other operators and functions that are auto-generated like this. The others are a default constructor, a copy constructor, a move constructor, a move assignment operator, and a destructor.

The default behavior of copy assignment is to copy each non-static member of the object -- there is a distinction between whether this copy is done "trivially", if the object is a POD type, or if it really performs a member-wise copy but the result is the same. There is also some complexity regarding situations in which it is not possible for the default copy behavior to be generated: if the class has a nonstatic member that is const; if it has a nonstatic member that itself does not have a copy assignment operator, etc.

As of C++11 you can opt out of having the compiler generate any of these special member functions via assigning them to the keyword delete.

For example in your code if you add

dummy& operator=(const dummy &) = delete;

to the definition of dummy, the program will no longer compile.

jwezorek
  • 8,592
  • 1
  • 29
  • 46