c++析构函数调用问题:为啥调用了四次,而构造函数只调用了2次?

c++析构函数调用问题:为啥调用了四次,而构造函数只调用了2次?,第1张

构造函数是由语句circle cobj(3,4);和circle cobq(5,6);调用的,另外两次是由复制构造函数生成临时类对象,发生在函数face()的参数传递的时候,由于你没有提供复制构造函数,系统会自动生成,所以程序结束前,需要4次调用析构函数。

对的,当使用引用传递时,无需用复制构造函数生成新的对象,那么析构函数只需2次就可以了。

1)、构造函数在创建类对象的时候被自动调用,

2)、析构函数在类对象生命期结束时,由系统自动调用。

构造从类层次的最根处开始,在每一层中,首先调用基类的构造函数,然后调用成员对象的构造函数。析构则严格按照与构造相反的次序执行,该次序是唯一的,否则编译器将无法自动执行析构过程。

构造函数和析构函数都是由编译器隐式调用的。这些函数的调用顺序取决于程序的执行进入和离开实例化对象时所在的那个作用域的顺序。一般而言,析构函数的调用顺序和构造函数的调用顺序相反,但是,对象的存储类可以改变析构函数的调用顺序。

对于在全局作用域中定义的对象,它们的构造函数是在文件中所有其他函数(包括main)开始执行之前被调用的(但无法保证不同文件的全局对象构造函数的执行顺序)。对应的析构函数是在终止main之后调用的。

exit函数会迫使程序立即终止,而不会执行自动对象的析构函数。这个函数经常用来在检测到输入错误或者程序所处理的文件无法打开时终止程序。

abort函数与exit函数功能相似,但它会迫使程序立即终止,而不允许调用任何对象的析构函数。abort函数通常用来表明程序的非正常终止。

自动局部变量的构造函数是在程序的执行到达定义这个对象的位置时调用的,而对应的析构函数是在程序离开这个对象的作用域时调用的(即定义这个对象的代码完成了执行)。每次执行进入和离开自动对象的作用域时,都会调用它的构造函数和析构函数。如果程序调用了exit或abort函数而终止,则不会调用自动对象的析构函数。

静态局部对象的析构函数只调用一次,即执行首次到达定义这个对象的位置时。对应的析构函数是在main终止或程序调用exit函数时调用的。

全局对象和静态对象是以创建它们时相反的顺序销毁的。如果程序由于调用了exit函数而终止,则不会调用静态对象的析构函数。

如果你逐句注释掉main中的语句,就会发现

day3=f(day2);这句话导致输出了三句

Copy Constructor called和Destructor called

说明f函数生成了三个TDate实例,这三个分别是由:

TDate f(TDate Q),参数值传递

TDate R(Q);拷贝构造

return Q;生成一个Q的副本作为返回值

产生的

初学者一般不知道的是,return 也会造成一个副本的产生,这就是为什么很多类的成员函数的返回类型里要加&加了引用的话,就不会产生副本了

1 C

2 因为a是一个对象,因此答案为C,如果a是一个指针,则答案为B,例子参看教科书吧

3 B

4 A,因为声明指针和引用不调用构造函数,只有声明对象时候才会,析构函数也一样

5 错,必须当场初始化

7 错

8 对

9 C 正好反了

是对的哇。有什么问题?继承关系的构造函数和析构函数的执行顺序为:1、父类构造函数执行。2、子类构造函数执行。3、子类析构函数执行4、父类析构函数执行。组合关系的构造函数和析构函数执行顺序为:1、执行类成员对象的构造函数。2、执行类自己的构造函数。3、执行类自己的析构函数4、执行类成员的析构函数。你container有两个成员,one,two,所以在执行这个container构造函数之前执行object类的构造函数两次,Defaultconstructorforobject,然后执行自己的构造函数,输出Defaultconstructorforcontainer。下面的一样推理。

unity c#怎么调用析构函数

析构函数不能显式调用的 不过可以自己写一个函数,手工调用清理相关资源 msdn C# 编程指南 析构函数(C# 编程指南) 示例 请参见 发送反馈意见 析构函数用于析构类的实例。 备注 不能在结构中定义析构函数。只能对类使用析构函数

c# 如何显式调用析构函数

析构函数不能显式调用的

不过可以自己写一个函数,手工调用清理相关资源

msdn C# 编程指南

析构函数(C# 编程指南)

示例 请参见 发送反馈意见

析构函数用于析构类的实例。

备注

不能在结构中定义析构函数。只能对类使用析构函数。

一个类只能有一个析构函数。

无法继承或重载析构函数。

无法调用析构函数。它们是被自动调用的。

析构函数既没有修饰符,也没有参数。

c++ 析构函数的调用

c++ 析构函数

不能在自己的应用程序中调用,其在对象的消亡时自动调用,用来做一些收尾工作,如释放资源等等

析构函数怎么现实调用啊

析构函数不需要你去直接调用,任何对象(类的实例)被删除之后,系统都会自动调用析构函数。

一般的,如果你用new创建对象,那么在delete的时候,会调用对象的析构函数。如果对象是全局变量或者局部自动变量,则在这个变量的生存期结束的时候调用析构函数,比如局部自动变量是在函数返回的时候被删除,这个时候会调用析构函数。

c++中 析构函数中可以调用虚函数么

c++中 析构函数中不可以调用虚函数。

effective C++ 中有这样的描述:同样的原因也适用于析构过程。一旦派生类析构函数运行,这个对象的派生类数据成员就被视为未定义的值,所以 C++ 就将它们视为不再存在。

C++中派生类在构造时会先调用基类的构造函数再调用派生类的构造函数,析构时则相反,先调用派生类的析构函数再调用基类的构造函数。

假设一个派生类的对象进行析构,首先调用了派生类的析构,然后在调用基类的析构时,遇到了一个虚函数,这个时候有两种选择:Plan A是编译器调用这个虚函数的基类版本,那么虚函数则失去了运行时调用正确版本的意义;Plan B是编译器调用这个虚函数的派生类版本,但是此时对象的派生类部分已经完成析构,“数据成员就被视为未定义的值”,这个函数调用会导致未知行为。

在c++中,派生类析构函数调用基类析构函数的方法

不是显式调用的吧

析构函数在何时调用

调用时间:

1、对象生命周期结束,被销毁时;

2、delete指向对象的指针时,或delete指向对象的基类类型指针,而其基类虚构函数是虚函数时;

3、对象i是对象o的成员,o的析构函数被调用时,对象i的析构函数也被调用。

C++当中的析构函数格式如下:

如以下定义是合法的:

当程序中没有析构函数时,系统会自动生成以下析构函数:

<类名>::~<类名>(){},即不执行任何 *** 作。

下面通过一个例子来说明一下析构函数的作用:

最后输出:析构函数被调用。

cinget() 表示从键盘读入一个字符,为了让我们能够看得清楚结果。当然,析构函数也可以显式的调用,如 (t)~T(); 也是合法的。

构造函数(析构函数)中调用虚函数

根据Effective C++ (3rd Edition) ---- Item 9:

Never call virtual functions during construction or destruction

(不要在构造函数和析构函数中调用虚函数)

其中举例为:(英文)

class Transaction {

public:

Transaction();

virtual void LogTransaction() const = 0;

};

Transaction::Transaction()

{

LogTransaction();

}

class BuyTransaction : public Transaction {

public:

virtual void LogTransaction() const;

};

Consider what happen when this code is executed:

BuyTransaction b;

Clearly a BuyTransaction constructor will be called, but firt, a Transaction constructor must be called; base class parts of derived class objects are constructed before derived class parts are The last line of the Transaction constructor calls the virtual function longTransaction, but this is where the surprise es in The version of logTransaction that't called is the one in Transaction, not the one in BuyTransaction -- even though the type of object being created is BuyTransaction During base class construction, virtual functions never go down into derived classes Instead, the object behaves as if it were of the base type Informally speaking, during base class construction, virtual functions aren't

There's a good reason for this seemingly counterintuitive behavior Because base class constructors execute before derived class constructors, derived class data members have not been initialized when base class constructors run If virtual functions called during base class construction went down to derived classes, the derived class functions would almost certainly refer to local data members, but those data members would not yet have been initialized That would be a non-s ticket to undefined behavior and late-night debugging sessions Calling down to parts of an object that have not yet been initialized is inherently dangerous so C++ gives you no way to do it

根据上面的原文看:调用的结果是(可能发生未定义行为)

这是由于(上例中)在BuyTransaction构造函数执行时,先执行基类(Transaction)的构造函数,而在Transaction的构造函数中又调用了(纯)虚函数logTransaction(),由于现在是在派生类里边定义函数,所以调用的logTransaction是BuyTransaction()里边的函数。这样有违背了你的初衷(调用Transaction里边的logTransaction())

如果在虚函数里边有对派生类成员(不是从基类那里继承来的)的 *** 作,那么更遭,以为在调用基类构造函数调时(派生类的成员还没有被初始化),这样就会导致未定义行为。

你最好看看原文的解释(英文部分)!

总之,记住不要在构造函数(析构函数)中调用虚函数!

C#里可以手动调用对象的析构函数吗

不可以,构造函数和析构函数都不能显式调用,而是在类的实例生命期开始和结束时分别自动执行的。

什么是c#析构函数

析构函数和构造函数正好相反

构造函数是和类同名没有返回值

析构函数是在类名前加~也没有返回值

构造函数上在对象创建时执行

析构函数是在程序结束时执行

一般时候析构函数里面写的都是一些资源回收之类的东西

不过C#的析构函数的调用机制和C++不同并不能保证每次都会调用所以最好不要利用C#的析构函数来回收资源

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/12157721.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-21
下一篇2023-05-21

发表评论

登录后才能评论

评论列表(0条)

    保存