C++中析构函数的行为

C++中析构函数的行为,c++,C++,我只是不明白为什么在将对象作为参数传递给另一个类的构造函数时调用析构函数。 这是出现问题的代码部分: Ocean* sea=new Ocean(4,3,7); sea->print(); RunLengthEncoding* s2= new RunLengthEncoding(*sea); sea->print(); 建造商的代码: RunLengthEncoding::RunLengthEncoding(Ocean sea) { oceanEncoding = new MyLin

我只是不明白为什么在将对象作为参数传递给另一个类的构造函数时调用析构函数。 这是出现问题的代码部分:

Ocean* sea=new Ocean(4,3,7);
sea->print();
RunLengthEncoding* s2= new RunLengthEncoding(*sea);
sea->print();
建造商的代码:

RunLengthEncoding::RunLengthEncoding(Ocean sea)
{
oceanEncoding = new MyLinkedListD();
height = sea.height();
width=sea.width();
starveT=sea.starveTime();
int length=1;
int cellType=sea.cellContents(0,0);
int hunger=sea.sharkFeeding(0,0);
for(int row=0;row<height;row++){
    for(int col=0;col<width;col++){
        if(row==0&&col==0){
            cellType=sea.cellContents(col,row);
            hunger=sea.sharkFeeding(col,row);
        }
        else{
            if(sea.cellContents(col,row)==cellType && ((cellType==Ocean::SHARK && hunger==sea.sharkFeeding(col,row))|| cellType!=Ocean::SHARK)){
                    length++;
            }
            else{
                oceanEncoding->add(cellType,length,hunger);
                cellType=sea.cellContents(col,row);
                length=1;
                hunger=sea.sharkFeeding(col,row);
            }
        }
    }
}
oceanEncoding->add(cellType,length,hunger);
internalPointer=oceanEncoding->getHead();
check();

}

构造函数正在按值获取其参数。当构造函数返回时,将创建、使用并销毁副本


按引用获取参数const reference最好。

构造函数按值获取参数。当构造函数返回时,将创建、使用并销毁副本

RunLengthEncoding(*sea);
引用参数const reference是最好的

RunLengthEncoding(*sea);
这需要一个值。不是指向值的指针,也不是对值的引用。编译器插入代码以创建值,并将其传递给函数。在函数内部,如果修改值,它不会更改您想象传递的值。调用函数后,值被销毁

*sea不会传递到函数中。它不能在函数内部修改

这需要一个值。不是指向值的指针,也不是对值的引用。编译器插入代码以创建值,并将其传递给函数。在函数内部,如果修改值,它不会更改您想象传递的值。调用函数后,值被销毁



*sea不会传递到函数中。它不能在函数内部修改。

因为一旦函数在对象上,构造函数就会按值获取其参数,因此对象超出范围并被销毁。由于您无法更改构造函数的参数,因此对象将始终被销毁,因此唯一的解决方法是创建在堆上分配的对象的新副本,这样它就不会被销毁。然而,这并不是很好的编码实践

,因为一旦函数覆盖对象,构造函数将按值获取其参数超出范围,因此被摧毁。由于您无法更改构造函数的参数,因此对象将始终被销毁,因此唯一的解决方法是创建在堆上分配的对象的新副本,这样它就不会被销毁,但是这并不是很好的编码实践

您需要显示所调用函数的签名,我的水晶球说它是按值取参数的。你怎么知道析构函数被调用了?当我在构造新对象后打印它时,它会打印出来rubbish@MaiIbrahim:这绝不是检测dtor是否运行的方法。@Maibrahim如果您的第二次打印调用是打印垃圾,然后我猜这个Ocean类正在管理一些资源,您可能还没有实现一个复制构造函数,或者如果您已经实现了,它还没有正确实现。这就是析构函数释放资源的原因,并留下一个指向无效资源的对象。了解。您需要显示正在调用的函数的签名,我的水晶球说它是按值取参数的。你怎么知道析构函数被调用了?当我在构造新对象后打印它时,它会打印出来rubbish@MaiIbrahim:这绝不是检测dtor是否运行的方法。@Maibrahim如果您的第二次打印调用是打印垃圾,然后我猜这个Ocean类正在管理一些资源,您可能还没有实现一个复制构造函数,或者如果您已经实现了,它还没有正确实现。这就是析构函数释放资源的原因,并留下一个指向无效资源的对象。请阅读。我无法更改构造函数的参数,它是由我的讲师编写的。通常情况下,一个编写的副本构造函数的签名如下:foocont Foo&other。ANSARE猜测构造函数可能看起来像这个foooo-other@MaiIbrahim:然后调用析构函数,简单的说。构造函数获取对象的副本,而不是对对象的引用,也不是指向对象的指针。这意味着将创建一个副本。当构造函数返回时,副本将超出范围,因此调用析构函数。您的老师正在指导您编写您永远不会在实际应用程序中编写的代码。我无法更改构造函数的参数,因为它是由我的讲师编写的。通常情况下,一个人编写的副本构造函数的签名如下:foocont Foo&other。Answare猜测构造函数可能看起来像这个Fooo other。@Maibrahim:然后将调用析构函数,就这么简单。构造函数获取对象的副本,而不是对对象的引用,也不是指向对象的指针。这意味着将创建一个副本。当构造函数返回时,副本将超出范围,因此调用析构函数。你的老师正在指导你编写你永远不会在实际应用程序中编写的代码。我知道,我不希望它被修改,但我想象的是,它会将它的副本发送到函数,执行函数,销毁副本
另一个保持原样,我想我知道发生了什么。您有一个复制构造函数,它将sea对象的内部内容传递给临时对象,以便它们共享这些内容。当暂时的东西被摧毁时,它会摧毁一些海洋仍然珍视的部分。在你的复制构造函数中,你需要创建一个指向海洋的任何东西的内部结构的副本。我知道问题出在哪里,但我仍然不知道如何解决它,我已经尝试在构造函数中创建一个指向海洋的指针,但它不会改变任何东西。我知道,我不想修改它,但我想象的是,它会将它的一个副本发送到函数,执行函数,销毁副本,另一个保持原样。我想我知道发生了什么。您有一个复制构造函数,它将sea对象的内部内容传递给临时对象,以便它们共享这些内容。当暂时的东西被摧毁时,它会摧毁一些海洋仍然珍视的部分。在你的复制构造函数中,你需要创建一个指向海洋的任何东西的内部结构的副本。我已经知道了问题所在,但我仍然不知道如何解决它,我已经尝试在构造函数中创建一个指向海洋的指针,但它不会改变任何东西。