Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
554 views
in Technique[技术] by (71.8m points)

c++ - Difference between , and ;?

EDIT Looks like I didn't explain myself in a good way. My question was not about the Rule of 3, or how to implement it in a good way. My question is why when using comma the destructors are called after complete the sequence and not when the variables leave the scope, I mean, the objets are only destroyed when all the functions between comma have finished, you can see it adding a cout to the destructors.

In this example,

#include <iostream>    
#include <cstring>    
using namespace std;    

class Libro {    
 char* titulo_; int paginas_;    
 public:    
 Libro() : titulo_(new char[1]), paginas_(0) {*titulo_= 0;}    
 Libro(const char* t, int p) : paginas_(p) {    
  titulo_ = new char[strlen(t) + 1];    
  strcpy(titulo_, t);    
}    
 ~Libro() { delete[] titulo_; }    
 void paginas(int p) { paginas_ = p; }    
 int paginas() const { return paginas_; }    
 char* titulo() const { return titulo_; }    
};    

void mostrar(Libro l) {    
cout << l.titulo() << " tiene " << l.paginas() << " paginas" << endl;    
}    

int main() {    
 Libro l1("Fundamentos de C++", 474), l2("Por Fin: C ISO", 224), l3;    
 l3 = l1;    
 mostrar(l1), mostrar(l2), mostrar(l3);  
}

Despite the copy constructor is not defined and the default copy constructor provide by the compiler is not valid in this case, the execution is correct and It shows the right information in the calls to mostrar(l1), mostrar(l2), mostrar(l3);.

However, if we use mostrar(l1); mostrar(l2); mostrar(l3); instead, we would have the expected error, the last call wouldn't show correctly the last call, because the copy haven't been done properly. Do you know what is the diference between use , and ;? Why this code is working when you use ,?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You have not written a copy constructor or a copy assignment operator. The Rule of 3 tells us that anytime a destructor has been written, the copy assignment operator and copy constructor should be as well. You haven't written either so let's look at what happens:

  1. l3 = l1 in this line the implicitly defined copy assignment operator is called which will be defined like this:

Libro& Libro::operator=(const Libro& rhs) {
    this.tiulo_ = rhs.titulo_;
    this.paginas_ = rhs.paginas_;
}
  1. this.tiulo_ = rhs.titulo_ This means that both the l1 and l3 objects point to the "Fundamentos de C++" string that was dynamically allocated by l1's constructor
  2. l3.~Libro() is called implicitly as l3 leaves scope which will call delete [] titulo_ destroying the "Fundamentos de C++" dynamically allocated member of l3 which is also l1's titulo_ member.
  3. l1.~Libro() is called implicitly as well, which will call delete [] titulo_ however this time that member was deleted by l3 leaving scope, for a deleted pointer:

Passing it to a deallocation function (double-delete) is undefined behavior

So your issue is not the , versus the ; but the double-delete that results from not following The Rule of 3.


If I may though, rather than suggesting you create a copy constructor and copy assignment operator, I'd suggest you do away with Libro and use string in a `pair your code would be as simple as this:

pair<string, int> l1 = make_pair("Fundamentos de C++"s, 474), l2 = make_pair("Por Fin: C ISO"s, 224), l3;

This will of course require you to explicitly output each member, for example:

cout << l1.first << " tiene " << l1.second << " paginas
" << l2.first << " tiene " << l2.second << " paginas
" << l3.first << " tiene " << l3.second << " paginas
";

Live Example


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...