推广 热搜: csgo  vue  angelababy  2023  gps  新车  htc  落地  app  p2p 

基于的析构函数(new、free关系会调用对象)

   2023-06-16 网络整理佚名2180
核心提示:因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符。这就说明:对于内建简单数据类型,和[]功能是相同的。内部数据类型没有析构函数,所以问题不大。抽象类中不仅包括纯虚函数,也可包括虚函数。思路:将x转化为2进制,看含有的1的个数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。

1.新的,,,自由关系

会调用对象的析构函数,new对应的free只会释放内存,new会调用构造函数。 free是C++/C语言的标准库函数,new/是C++的运算符。

它们可以用来申请动态内存和释放内存。 对于非内部数据类型的对象,单独使用maloc/free不能满足动态对象的要求。

对象在创建时必须自动执行构造函数,对象在死亡前必须自动执行析构函数。

由于/free是库函数而不是操作符,不在编译器的控制权限之内,执行构造函数和析构函数的任务不能强加给/free。

因此,C++语言需要一个可以完成动态内存分配和初始化的 new,以及一个可以完成清理和释放内存的。 请注意,new/ 不是库函数。

2.与[]的区别

析构函数只会被调用一次,而 [] 会调用每个成员的析构函数。

More C++中有更详细的解释:“当运算符用在数组上时,它会为每个数组元素调用析构函数,然后调用释放内存。” 匹配新的,[]匹配新的[]

MemTest *mTest1 = new MemTest[10];

MemTest *mTest2 = new MemTest;

Int *pInt1 = new int [10];

Int *pInt2 = new int;

delete[]pInt1; //-1-

delete[]pInt2; //-2-

delete[]mTest1;//-3-

delete[]mTest2;//-4-

在-4-报错。

也就是说:对于内置的简单数据类型,[]的作用是一样的。

对于自定义复杂数据类型,[] 不能互换使用。 [] 删除一个数组,删除一个指针。

简单的说就是删除new分配的内存; 用new[]分配的内存用[]删除。 [] 将调用数组元素的析构函数。

内部数据类型没有析构函数,所以没什么大不了的。 如果不带括号使用它,它会认为它指向单个对象,否则,它会认为它指向一个数组。

3、C++有哪些特性(面向对象的特性)

封装、继承和多态。

4、子类析构时是否应该调用父类的析构函数?

析构函数的调用顺序是先析构派生类,再析构基类,也就是说,当调用析构基类时,派生类的所有信息都被销毁了.

定义对象时,先调用基类的构造函数,再调用派生类的构造函数; 析构时正好相反:先调用派生类的析构函数,再调用基类的析构函数。

5.多态、虚函数、纯虚函数

多态性:当不同的对象收到相同的消息时,会产生不同的动作。 C++的多态性体现在运行和编译两个方面:程序运行时的多态性体现在继承和虚函数上;

多态性体现在程序编译时函数和运算符的重载;

虚函数:基类中用关键字标记的成员函数。 它提供了一个接口接口。 允许在派生类中重新定义基类虚函数。

纯虚函数的作用:在基类中为其派生类保留一个函数名,以便派生类根据需要定义。 纯虚函数作为接口,不具备函数的功能,一般不能直接调用。

从基类继承的纯虚函数在派生类中仍然是虚函数。 如果一个类至少有一个纯虚函数,那么这个类就称为抽象类(class)。

抽象类不仅包括纯虚函数,还包括虚函数。 抽象类必须作为派生其他​​类的基类,不能用来直接创建对象实例。 但是,使用指向抽象类的指针仍然支持运行时多态性。

6.找到下面函数的返回值(微软)

int func(x) 
    int countx = 0
    while(x) 
    { 
        countx ++; 
        x = x&(x-1); 
    } 
    return countx; 

假设 x = 9999。答案:8

思路:将x转为二进制,看包含1的个数。

7. 什么是“参考”? 声明和使用“引用”时应注意哪些问题?

答:引用是目标变量的“别名”(alias),对应用程序的操作与直接对变量的操作是完全一样的。

声明引用时,请记住对其进行初始化。

引用声明后,意味着目标变量名有两个名字,即目标原名和引用名,引用名不能作为其他变量名的别名。

声明一个引用并没有定义一个新的变量,只是说明引用名是目标变量名的别名,本身不是数据类型,所以引用本身不占用存储单元,系统不为引用分配存储单元。 无法创建对数组的引用。

8、使用“引用”作为函数参数有什么特点?

(1) 传递对函数的引用与传递指针具有相同的效果。

此时被调用函数的形参作为原调用函数中实参变量或对象的别名,所以被调用函数中对形参变量的操作就是对应的目标对象(在调用函数中函数)调用函数)操作。

(2) 函数的参数是引用传递的,不会在内存中生成实参的副本,直接对实参进行操作; 而函数的参数是通过普通变量传递的,当函数调用发生时,需要为形参单元分配存储,形参变量是实参变量的拷贝;

如果传递了一个对象,复制构造函数也会被调用。 因此,当参数传递的数据量很大时,引用的效率和占用空间都优于一般变量。

(3)虽然使用指针作为函数参数也可以达到使用引用的效果,但是在被调用的函数中,存储单元也必须分配给形参,以"*指针变量名的形式进行操作"需要重复。 这样容易出错,程序的可读性差; 另一方面,在调用函数的调用点,变量的地址必须用作实际参数。 另一方面,引用更易于使用且更清晰。

9.什么时候需要使用“常量引用”?

如果要使用引用来提高程序的效率,保护传递给函数的数据在函数中不被更改,就应该使用常量引用。

常量引用声明方式:const类型标识符&引用名=目标变量名;

portant;word-break: inherit !important;">例1int a;

const int &ra=a;

ra=1//错误

a=1//正确

2

string foo( );

void bar(string & s);

那么下面的表达式将是非法的:

bar(foo( ));

bar("hello world");

原因是foo()和"hello world"字符串都会生成一个临时对象,而在C++中,这些临时对象都是const类型的。

所以上面的表达式是试图将一个const类型的对象转换为一个非常量类型,这是不合法的。 引用参数能定义为const的,尽量定义为const。

10. 使用“引用”作为函数的返回值类型有什么格式、好处和规则?

格式:类型标识符&函数名(形式参数列表和类型描述){ //函数体}

好处:返回值在内存中没有副本; (注:正因如此,不建议返回局部变量的引用。因为随着局部变量生命周期的结束,对应的引用也将失效,产生错误!

防范措施:

(1) 不能返回对局部变量的引用。 这篇文章可以参考C++[1]的Item 31。 主要原因是局部变量在函数返回后会被销毁,所以返回的引用变成了“空”引用,程序会进入未知状态。

(2)函数内部new分配的内存引用不能返回。 这篇文章可以参考C++[1]的Item 31。 虽然不存在局部变量被动销毁的问题,但是对于这种情况(返回函数内部new分配的内存的引用),又面临其他尴尬的情况。 例如,函数返回的引用只是作为一个临时变量出现,并没有被赋值实际变量,那么引用指向的空间(new分配的)就无法释放,造成泄漏。

(3) 可以返回类成员的引用,但最好是const。 这个原理可以参考C++[1]的Item 30。 主要原因是当一个对象的属性与某个业务规则(规则)相关联时,其赋值往往与其他一些属性或对象的状态相关,因此需要将赋值操作封装在一个业务规则中。 如果其他对象可以获得对该属性的非常量引用(或指针),那么仅仅对该属性赋值就会破坏业务规则的完整性。

(4) 流运算符重载的返回值声明为“引用”:

流操作符,这两个操作符往往被期望连续使用,例如:cout

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON