关于#c++#的问题:而在转移所有权之后打印a会报错,即使这样a的print方法任然可以执行

unique_ptr的被移除所有权的对象任然能执行原先的方法:

#include<iostream>
#include<memory>
#include<string>
#include<map>

class Entity{
public:
    Entity(){
        std::cout<<"构造函数\n";
    }
    void print(){
        std::cout<<"good job\n";
    }
    ~Entity(){
        std::cout<<"析构函数\n";
    }
};

int main(){

    std::unique_ptr<Entity> a(new Entity());
    std::unique_ptr<Entity> b = std::move(a);
    // std::cout<<a<<" "<<b;
    a->print();
    b->print();
    return 0;
}

执行结果如下:

构造函数
good job
good job
析构函数

而在转移所有权之后打印a,则会报错,即使这样a的print方法任然可以执行,这是为什么。

基于Monster 组和GPT的调写:

  • 在代码中,使用了std::unique_ptr来管理Entity对象的所有权。当调用std::move(a)时,所有权从a转移到了b,这意味着b现在拥有了Entity对象的所有权,而a不再拥有。
  • 当你调用a->print()时,虽然a不再拥有对象的所有权,但它仍然保留了指向对象的指针。因此,调用a->print()仍然可以正常执行,因为指针仍然有效。
  • 然而,当程序结束时,b被销毁并调用其析构函数,因为它拥有对象的所有权。因此,在程序结束时,你会看到析构函数的输出。
  • 而如果你尝试打印a,会导致错误。因为a不再拥有对象的所有权,它不再指向有效的对象。所以,当你尝试访问a时,会出现未定义行为。在这种情况下,你可能会遇到程序崩溃或产生其他不可预测的结果。
  • 总之,移动所有权后,被移除所有权的对象可以继续执行其方法,但需要注意确保不要访问已经失效的指针。

你改一下你的代码就清楚了

#include<iostream>
#include<memory>
#include<string>
#include<map>

class Entity {
    int d;
public:
    Entity(int a):d(a) {
        std::cout << "构造函数\n";
    }
    void print() {
        std::cout << "good job\n"<<d;
    }
    ~Entity() {
        std::cout << "析构函数\n";
    }
};

int main() {
    int c=1;
    int d;
    d = std::move(c);
    std::unique_ptr<Entity> a(new Entity(10));
    std::unique_ptr<Entity> b = std::move(a);
    // std::cout<<a<<" "<<b;
    a->print();
    b->print();
    return 0;
}


执行改过的代码,你会发现报错,因为他访问了成员变量。所谓的类的非静态函数,所有这个类共享同一段代码,区分由哪个对象调用则通过this指针来区分。move之后,a所持有的对象已经移动到了b,a不持有任何对象,a->print()相当于(Entity)NULL->print(),也就是说this是空,如果不访问成员,不会出错。访问必然出错。
你可以试一下 Entity * a=nullptr; a->print()这样的代码