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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/daaikuaichuan/article/details/89072180

一、面向对象的基本概念

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

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

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

obj (const obj &a);

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

obj& operate=(const obj &a);

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

  • 类的对象直接作为函数参数(值传递)

  • 类的对象直接作为函数返回值;

  • 用类的一个对象构造另一个对象。

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

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

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

六、深拷贝与浅拷贝

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

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

【浅拷贝】:
在这里插入图片描述
【深拷贝】:
在这里插入图片描述

七、友元

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

#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;
}

猜你喜欢

转载自blog.csdn.net/daaikuaichuan/article/details/89072180