复制构造函数动机 - 为什么我的程序不崩溃?

Copy constructor motivation - why my program don't crash?

本文关键字:程序 崩溃 我的 为什么 构造函数 动机 复制      更新时间:2023-10-16

我了解到使用复制构造函数的动机之一是避免程序中的以下崩溃-

#include <iostream>
using namespace std;
class Employee {
public:
    Employee(int ID,char const * name){...};
    ~Employee(){...};
    // Methods
    void Print();
private:
    // members
    int m_ID;
    char* m_name;
};
void MyFunc(Employee emp) {
    cout << "in MyFunc n ";
}
int main() {
    Employee One(1,"Garen Torosian");
// calling copy constructor
    MyFunc(One);
    cout << "In the end of main n";
// Here the program crashes!
    return 0;
}

正如你所看到的,该程序应该在return 0;之前崩溃,但当我运行该程序时,它运行良好,并正常终止,为什么?

编辑:在这种情况下,程序确实崩溃-

// Employee.h
#include <iostream>
using namespace std;
class Employee {
public:
   Employee(int ID, 
                   const char* name);
  ~Employee();
  // Methods
  void Print();
private:
  // members
  int   m_ID;
  char* m_name;
};

// Employee.cpp
#include "Employee.h“
Employee::Employee(int iID, const char *name){ // Ctor
  cout << "Constructor called" << endl;
  m_ID = iID;
  m_name = new char [strlen(name) +1];
  strcpy(m_name, name);
  Print();
}
void Employee::Print() { // Print
cout << "ID: " << m_ID << ",Name:” << m_name
<< " ,Address(pointer):0x" << hex << (int) m_name<< endl;
}
Employee::~Employee() { // Dtor
  cout << "Destructor called"<<endl;
  Print();
  delete [] m_name;
  m_name=NULL;
}

void MyFunc(Employee emp) {
  cout << "in MyFunc n ";    
}
int main()
{
    Employee One(1,"Eli Rachamim");
// calling copy constructor
MyFunc(One);
cout<< "In the end of main n“;
// Here the program crashes! 
return 0;
}

如果d-tor类似

~Employee(){ delete[] name; }

并且您为char*指针分配内存,并且您没有copy c-tor,而执行memberwise-copy的编译器生成的copy c-tor将在复制对象时被调用。所以,会有double-free,在大多数情况下,它会给你memory dump(在实际中,对已经被破坏的对象调用析构函数是UB,对已经删除的对象调用delete[]也是UB)。但如果您不使用内存copy c-tor,编译器生成的就可以很好地工作。

编辑

所以,第二个示例演示了d-tor对allready析构函数对象以及double-free的调用。

为什么你认为它应该崩溃?

C++有一个不幸的特性,如果你不提供一个自动生成的复制构造函数,那么它就会提供一个,而你的MyFunc()并没有真正做任何会被自动生成的副本搞砸的事情。