首页 > 其他分享 >面向对象(构造、析构、拷贝、赋值、友元)

面向对象(构造、析构、拷贝、赋值、友元)

时间:2023-08-29 11:33:10浏览次数:33  
标签:友元 面试题 调用 函数 面向对象 析构 拷贝 构造函数



文章目录

  • 一、面向对象的基本概念
  • 1、面试题--->面向对象的基本原则?
  • 2、面试题--->空类会创造哪些成员函数?
  • 二、类和结构体
  • 1、面试题--->类和结构体的区别?
  • 三、成员变量及其初始化
  • 四、构造函数和析构函数
  • 1、构造函数和析构函数的调用顺序
  • 2、面试题--->析构函数为什么要定义为虚函数?
  • 3、面试题--->为什么构造函数不能是虚函数?
  • 4、面试题--->是否可以把每个函数都声明为虚函数?
  • 5、面试题--->析构函数可以是内联函数吗?
  • 6、面试题--->析构函数可以抛出异常吗?
  • 7、面试题--->构造函数和析构函数为什么不能有返回值?
  • 8、面试题--->构造函数无返回值,那如何判断对象是否“构造”成功?
  • 9、为什么调用子类的析构函数后会再调用基类的析构函数?
  • 五、拷贝构造函数和赋值函数
  • 1、面试题--->什么时候会调用拷贝构造函数?
  • 2、面试题--->什么时候会调用默认拷贝构造函数?
  • 六、深拷贝与浅拷贝
  • 七、友元


一、面向对象的基本概念

1、面试题—>面向对象的基本原则?

面向对象的三大原则:继承、封装、多态

  • 继承:子类继承了父类的数据成员和成员函数
  • 封装:隐藏对象的属性和实现细节,仅对外公开接口,控制访问权限(比如private)
  • 多态:同一种方法在子类和父类中有不同的表现,即:一种接口,多种方法

2、面试题—>空类会创造哪些成员函数?

默认构造函数、析构函数、拷贝构造函数、赋值构造函数

二、类和结构体

1、面试题—>类和结构体的区别?

类和结构体的区别在于class中的成员默认是private的,而struct默认是public的。struct也可以拥有构造函数和析构函数,以及继承等等

三、成员变量及其初始化

class test
{
public:
	test(int val) : a(val){} // 常量或者引用类型必须在初始化列表中初始化
private:
	const int a;
	static int b;
}
// 静态数据成员在类外初始化
int test::b = 0;

四、构造函数和析构函数

1、构造函数和析构函数的调用顺序

  • 建立对象时,会先调用父类的构造函数再调用子类的构造函数
  • 销毁对象时,会先调用子类的析构函数再调用父类的析构函数

2、面试题—>析构函数为什么要定义为虚函数?

如果将父类的析构函数定义为虚函数,那么子类的析构函数将自动变为虚函数,在销毁对象时,就会先调用子类的析构函数再调用父类的析构函数

3、面试题—>为什么构造函数不能是虚函数?

虚函数需要被某个对象调用,而构造函数主要就是用来实例化一个对象,所以虚函数的调用肯定是在构造函数之后的

4、面试题—>是否可以把每个函数都声明为虚函数?

原则上没有什么问题,但是不建议这样做,因为每声明一个虚函数都会添加到虚函数表中,将所有函数都声明为虚函数会增加系统开销

5、面试题—>析构函数可以是内联函数吗?

构造函数和析构函数可以是内联函数,但是不建议这样做,因为内联函数只适合体积较小、逻辑简单的函数

6、面试题—>析构函数可以抛出异常吗?

【Effective C++】不要让异常逃离析构函数!如果析构函数某一处发生异常,那么异常点之后的程序都不会执行,如果在异常点之后还有一些释放资源的操作,那么就会造成资源泄露

7、面试题—>构造函数和析构函数为什么不能有返回值?

构造函数不需要用户调用,在创建一个对象时会自动执行构造函数,当然也可以直接调用构造函数。构造函数返回的就是这个类的对象this指针,这是不能改变的,默认的。所以构造函数不能指定返回值。

析构函数不带任何参数是因为析构函数仅仅只是负责对类指针成员指向的空间进行释放,不需要有任何参数。也不需要返回值。

8、面试题—>构造函数无返回值,那如何判断对象是否“构造”成功?

  • 在C++构造函数中抛出异常,但要注意资源泄漏问题,因为C++拒绝为没有完成构造函数的对象调用析构函数;
  • 向C++构造函数多传递一个标志参数,通过该参数来判断对象是否构造成功

9、为什么调用子类的析构函数后会再调用基类的析构函数?

这是C++的规定,这样做也是为了防止内存泄漏。当在基类的构造函数中申请了资源的时候,派生类因为继承了基类,也就继承了基类的资源,所以析构的时候也要调用基类的析构函数。

面向对象(构造、析构、拷贝、赋值、友元)_构造函数

五、拷贝构造函数和赋值函数

拷贝构造函数是一种特殊的构造函数,用类的一个对象构造和初始化另一个对象时,会调用拷贝构造函数

obj (const obj &a);

用类的一个对象给该类的另一个对象赋值时,会调用赋值函数

obj& operate=(const obj &a);

1、面试题—>什么时候会调用拷贝构造函数?

  • 类的对象直接作为函数参数(值传递)
  • 类的对象直接作为函数返回值;
  • 用类的一个对象构造另一个对象。

2、面试题—>什么时候会调用默认拷贝构造函数?

  • 如果用户没有自定义拷贝构造函数,并且在代码中使用到了拷贝构造函数,编译器就会生成默认的拷贝构造函数。但如果用户定义了拷贝构造函数,编译器就不在生成。
  • 如果用户定义了一个构造函数,但不是拷贝构造函数,而此时代码中又用到了拷贝构造函数,那编译器也会生成默认的拷贝构造函数。

六、深拷贝与浅拷贝

浅拷贝即用类的对象构造另一个对象或者赋值时,如果用户没有自定义拷贝构造函数或者赋值函数,就会使用默认的拷贝构造函数,当类中有指针变量时,浅拷贝只是拷贝了指针的地址,两个对象仍然指向同一块内存,而深拷贝则会开辟一块新的内存

浅拷贝的问题在于,析构对象时,同一块内存会被析构两次,因此造成内存错误

【浅拷贝】:

面向对象(构造、析构、拷贝、赋值、友元)_OOP_02


【深拷贝】:

面向对象(构造、析构、拷贝、赋值、友元)_析构函数_03

七、友元

对于类的私有数据成员,只有类的成员函数才能访问,友元的作用在于使得非成员函数可以访问类的私有成员,虽然提高了程序的运行效率,但也破坏了类的封装性

#include <iostream>
using namespace std;

class A
{
public:
    friend void set_show(int x, A &a); // 该函数是友元函数的声明
private:
    int data;
};
void set_show(int x, A &a)  // 友元函数定义,为了访问类A中的成员
{
    a.data = x;
    cout << a.data << endl;
}
int main(void)
{
    class A a;
    set_show(1, a);
    return 0;
}


标签:友元,面试题,调用,函数,面向对象,析构,拷贝,构造函数
From: https://blog.51cto.com/u_6526235/7273906

相关文章

  • C++面向对象进阶
    C++中的拷贝是啥意思?是利用一个已经存在的对象创建一个新对象,用已经存在的数据初始化新对象的内存。对象创建有两个阶段:1.分配内存2.进行初始化   是不是new关键字的使用s1(s2),s1=s2,s1=1,类似这种都是以拷贝的方式完成的初始化,区别只是有没有进行隐式的类型转......
  • 有了析构函数之后,为什么还要虚析构和纯析析构?
    我们知道析构函数释放父类的资源的,但如果子类中有属性开辟到堆区,那么父类是无法调用到子类的析构代码的,子类的占用的堆区内存如果没有得到释放,那么会造成内存泄漏。那么要让父类的指针能够调用子类的析构函数,释放子类的堆区内存,就要用到虚析构或者纯虚析构。虚析构......
  • 27面向对象(继承)
    动态方法与静态方法#动态方法1.绑定给对象的方法classStudent:defrun(self):prtin(self)#类调用绑定给对象的方法:有几个参数就需要传几个参数Student.run(123)#对象调用绑定给对象的方法:会自动将对象当做第一个参数传入......
  • 学习笔记 - Java 面向对象_下
    static关键字如果想让一个成员变量被类的所有实例所共享,就用static修饰即可,称为类变量(或类属性)可修饰结构:属性、方法、代码块、内部类对比静态变量和实例变量个数静态变量:只有一份,被多个对象共享;实例变量:每一个对象都保存着一份实例变量;内存位置静态变量:存放在堆......
  • 类定义、属性、初始化和析构知识点总结
    一:前言:为什么要学类?   类是一个独立存放变量(属性/方法)的空   1.简化代码,提升效率,避免代码重复写入。如用户注册、校验、登录方法可以放在一个类中,需要哪个方法就调用哪个类===》建立模型框架(建立一个方法)===》很多鼠标(实例化)===》都是独立的2.面向对象:直接给我......
  • java数组、面向对象的引入
    packagecom.momo.demo;publicclassMain{publicstaticvoidmain(String[]args){int[]arr=newint[3];System.out.println(arr);System.out.println(arr[0]);System.out.println(arr[1]);System.out.println(arr[2]);arr[0]=55;arr[2]=66;System.o......
  • 面向对象设计原则
    前言在面向对象的软件设计中,只有尽量降低各个模块之间的耦合度,才能提高代码的复用率,系统的可维护性、可扩展性才能提高。面向对象的软件设计中,有23种经典的设计模式,是一套前人代码设计经验的总结,如果把设计模式比作武功招式,那么设计原则就好比是内功心法。常用的设计原则有七个......
  • 什么是面向对象编程领域的胖接口 - Fat Interface
    在面向对象编程(Object-OrientedProgramming,简称OOP)领域,"胖接口",也称为"FatInterface",是一个被广泛认识并且应当避免的设计反模式。这个术语指的是一个接口(或抽象类)包含了大量的方法,可能超出了单一职责的原则,导致接口变得臃肿、复杂和难以维护。在本文中,我将详细解释什么是胖接......
  • C++面向对象、类和对象、访问控制限定符
    面向对象和面向过程面向过程:关注如何解决问题,以及解决问题的步骤面向对象:关注的解决问题的"人"即"对象",以及实现能解决问题的"对象"注意:面向对象的细节的本质上还是面向过程,因此面向对象不是解决问题的捷径,而是以更高的维度去思考问题面向对象的四个特性:抽象:先找出(想象)......
  • js面向对象编程
    基本概念面向对象编程将一个系统抽象为许多对象的集合,每一个对象代表了这个系统的特定方面。对象包括函数(方法)和数据。一个对象可以向其他部分的代码提供一个公共接口,而其他部分的代码可以通过公共接口执行该对象的特定操作,系统的其他部分不需要关心对象内部是如何完成任务的,这样......