C++ 复制构造函数错误地接受参数

C++ copy constructor incorrectly takes argument

我有以下行为异常的代码。到目前为止我理解的流程是,display(line); 将调用复制构造函数 Line::Line(const Line &obj),并且将传入 line 的引用。但是 cout<<"[origin] *ptr="<<*obj.ptr<<endl; 将打印 [origin] *ptr=32767 而不是 [origin] *ptr=10.

更奇怪的是,如果我取消注释// int x=3;,它会正确打印,但我真的不知道为什么。

您可以在以下位置找到可执行代码:https://www.onlinegdb.com/pjbPO0X1f

#include <iostream>
 
using namespace std;
 
class Line
{
   public:
      int getLength( void );
      Line( int len );
      Line( const Line &obj);

   private:
      int *ptr;
};
 
// constructor
Line::Line(int len)
{
    ptr=&len;
    cout<<"*ptr="<<(*ptr)<<endl;
}

// copy constructor
Line::Line(const Line &obj)
{
    // int x=3;
    cout<<"[origin] *ptr="<<*obj.ptr<<endl;
    ptr = new int;
    *ptr = *obj.ptr; // copy
}

int Line::getLength( void )
{
    return *ptr;
}
 
void display(Line obj)
{
   cout << "line=" << obj.getLength() <<endl;
}

int main( )
{
   Line line(10);
   display(line);
   return 0;
}

您的程序调用了 undefined behavior (UB)。当您的构造函数完成时:

Line::Line(int len)
{
    ptr=&len;
    cout<<"*ptr="<<(*ptr)<<endl;
} // ptr is dangling

指针 ptr 指向一个不再存在的局部变量 lenptr 现在悬空,任何取消引用它的尝试都会调用 UB。

您的程序可能会做任何事情。您还可以看到一些奇怪的结果,例如添加 int x = 3 导致您的程序“正常运行”。不用担心为什么会这样,这只是UB的结果。

这是一个常见的错误(虽然这是一个奇怪的版本)。

此代码错误

// constructor
Line::Line(int len)
{
    ptr=&len;
    cout<<"*ptr="<<(*ptr)<<endl;
}

ptr 指向 lenlen 是一个局部变量。它在构造函数退出时被销毁。这意味着您有一个指向不再存在的对象的指针。有时这被称为 悬挂指针

稍后在代码中使用此指针

cout<<"[origin] *ptr="<<*obj.ptr<<endl;

由于指针现在无效,影响不可预测。

使指针变得困难的许多事情之一是指针的生命周期和它所指向的对象的生命周期根本没有任何联系。由您来确保您的指针始终指向仍然 'alive'.

的对象