为什么程序在构造函数之后停止?

Why program stops after constructor?

我正在学习运算符重载,我在某处读到,当您将 r 值分配给对象时,它会创建一个临时对象,但该程序在为 r 值调用构造函数后停止。

Class.h

class Foo{
    int *num;

    public :

    Foo(int x);
    Foo& operator=(Foo &&rhs);
    Foo& operator=(const Foo &rhs);
    Foo(Foo &f);
    Foo(Foo &&f);
    void set(int x);
    void show();
    ~Foo();
    

};

Class.cpp

#include <iostream>
#include "class.h"
#include <cstring>

Foo::Foo(int x){
    num = new int;
    *num = x;
    std::cout << "Constructor for " << *num << std::endl;
};

Foo::~Foo(){
    std::cout << "Destructor for " << *num << std::endl;
    delete num;
}

void Foo::show(){
    std::cout << *num << std::endl;
}

void Foo::set(int x){ 
    *num = x;
    std::cout << "INSIDE SETTER" << std::endl;
}

Foo& Foo::operator=(Foo &&rhs){

    num = rhs.num;
    rhs.num = nullptr;
    return *this;
}

Foo& Foo::operator=(const Foo &rhs){

    *num = *rhs.num;
    return *this;
}


Foo::Foo(Foo &f){
    num = new int;
    *num = *f.num;
    std::cout << "Copy constructor used " << std::endl;
}

Foo::Foo(Foo &&f)
: num{f.num}{
    std::cout << "Move constructor used " << std::endl;
    f.num = nullptr;
}

int main(){
    Foo f1(10);
    Foo f2(20);
    Foo f3(30);
    f1.show();
    f2.show();
    f3.show();
    f1 = 60;
    f1.show();
    f2.show();
    f3.show();
    return 0;
}

程序在调用构造函数 60 后停止。

输出
10
的构造函数 20
的构造函数 30
的构造函数 10
20
30
60
的构造函数 [完成] 在 1.458 秒内以代码 =3221225477 退出

当我使用 char *str 而不是 int *num 时它有效

你的问题出在析构函数中。它尝试访问 *num,但将赋值运算符集 num 移动到 nullptr.

保护日志记录以防止 nullptr(不需要保护 delete,因为它保证在空指针上正常工作):

Foo::~Foo(){
    if (num) {
        std::cout << "Destructor for " << *num << std::endl;
    } else {
        std::cout << "Destructor for null pointer" << std::endl;
    }
    delete num;
}

或者在移动分配中使用交换并让 rhs 最终删除它(这也将修复内存泄漏:你永远不会删除 num 的旧值)

Foo& Foo::operator=(Foo &&rhs)
{
    std::swap(num, rhs.num);
    return *this;
}

swap 解的输出:

Constructor for 10
Constructor for 20
Constructor for 30
10
20
30
Constructor for 60
Destructor for 10
60
20
30
Destructor for 30
Destructor for 20
Destructor for 60