之间的区别,和;?

时间:2017-08-10 11:45:21

标签: c++ c++11

编辑看起来我没有以一种好的方式解释自己。我的问题不是关于3的规则,或者是如何以一种好的方式实现它。我的问题是为什么当使用逗号时,在完成序列后调用析构函数而不是在变量离开作用域时调用,我的意思是,当逗号之间的所有函数都已完成时,objets只会被销毁,你可以看到它在析构函数中添加了一个cout。

在此示例中,

#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);  
}

尽管没有定义复制构造函数,并且编译器提供的默认复制构造函数在这种情况下无效,但执行是正确的并且它在对 mostrar(l1),mostrar的调用中显示正确的信息( l2),mostrar(l3);

但是,如果我们使用 mostrar(l1); mostrar(L2); mostrar(l3); 相反,我们会有预期的错误,最后一次调用无法正确显示最后一次调用,因为副本没有正确完成。 你知道使用之间有什么不同吗?为什么这段代码在您使用时有效?

1 个答案:

答案 0 :(得分:2)

您尚未编写复制构造函数或复制赋值运算符。 The Rule of 3告诉我们,无论何时编写析构函数,复制赋值运算符和复制构造函数也应如此。你还没有写过,所以让我们来看看会发生什么:

  1. l3 = l1在此行中调用implicitly defined copy assignment operator,其定义如下:
  2. Libro& Libro::operator=(const Libro& rhs) {
        this.tiulo_ = rhs.titulo_;
        this.paginas_ = rhs.paginas_;
    }
    
    1. this.tiulo_ = rhs.titulo_这意味着l1l3对象都指向由l1的构造函数动态分配的“Fundamentos de C ++”字符串
    2. l3.~Libro()被隐式调用为l3 leaves scope,它会调用delete [] titulo_销毁动态分配l3 成员的“Fundamentos de C ++”也是l1的{​​{1}}成员
    3. titulo_也会被隐式调用,会调用l1.~Libro()但是这次会员被delete [] titulo_删除,留下范围for a deleted pointer
    4.   

      将其传递给释放函数(双删除)是未定义的行为

      因此,您的问题不是l3,,而是因为不遵循3规则而导致的双重删除。

      如果我可以,而不是建议你创建一个复制构造函数和复制赋值运算符,我建议你不要使用;并使用string在`对,你的代码将是这很简单:

      Libro

      这当然要求您明确输出每个成员,例如:

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

      Live Example