C++面试题

一,重载,重写,隐藏的区别

     1,重载与重写

                      作用域不同:重写存在于继承体系下,也就是两个类中的两个函数,

                                            重载存在于一个类中,也就是一个类中的两个函数。

                      参数列表不同:重写要求两个函数的参数列表完全相同,(协变和虚析构函数例外),且需要virtual修饰。

                                               重载要求两个函数参数必须有不同之处。

     2,隐藏与重写和重载的区别:

                       作用空间 :和重写一样,在继承体系下,也就是两个类中的两个函数。

                        参数列表:当没有virtual修饰时,参数列表可以相同,也可以不同,只需要函数名相同,就是隐藏。

                                          当有virtual修饰时,参数列表相同就是重写,参数列表不同就是隐藏。

总结:重载是静态绑定的,隐藏是动态绑定的,虽然两者都实现了多态,但是有本质的区别。

二,虚函数和纯虚函数的区别

    1,含有纯虚函数的类被称为抽象类,抽象类无法实例化对象,必须在派生类张对其进行重写才能使用。

           也就是说,纯虚函数是为派生类服务的。

          含有虚函数的类可以直接实例化对象,可以在派生类中对虚函数重写,也可以不重写。

三,简述C++三大特性

      1,封装:

                   定义:将同一事物的特性抽象出来,放到一个类中,并用访问限定符进行修饰,将部分代码模块隐藏。

                              对外仅提供接口和方法。提高代码的安全性

      2, 继承:

                基类派生出派生类,派生类继承基类 ,的代码模块(包括数据和函数),实现代码的复用,

               将类与类之间联系起来,是实现多态的基础。

      3,多态:

                   定义:通过在基类中定义虚函数,在派生类中重写虚函数,通过基类的指针或者引用指向派生类对象。

                               由于基类指针指向的类的类型不一样,那么就会调用不同的函数。

                              调用实现接口的高度统一,简而言之就是,调用相同的接口,表现不同的结果。接口复用

四,什么成员函数不能被声明为虚函数       

1,只有类的成员函数才能被声明为虚函数

2,静态成员函数不能被声明为虚函数

        静态成员函数是属于类中的,依赖类而存在,虚函数必须要知道具体的对象类型才能确定调用哪一个,依赖对象而存在。

        两者的依赖不同,终归是不能合二为一的。

3,构造函数不能被声明为虚函数

        构造函数完成对象的初始化,也包括虚函数表的初始化。

        虚函数的调用需要访问虚表,两者相互矛盾。

        这两个事件在不同的时间点发生,不能合二为一的。

4,析构函数可以是虚函数,并且尽可能声明为虚函数 

         

class Base
{
public:
	Base()
	{
		cout << "Bulid a new Base" << endl;
	}
	 ~Base()
	{
		cout << "Delete something in Base" << endl;
	}
};
class Device :public Base
{
public:
	Device()
	{
		cout << "Build a new Device" << endl;
	}
	~Device()
	{
		cout << "Delete something  in Device" << endl;
	}
};

int main()
{
	Base* p = new Device;
	delete p;
	return 0;
}

 

class Base
{
public:
	Base()
	{
		cout << "Bulid a new Base" << endl;
	}
	 virtual~Base()
	{
		cout << "Delete something in Base" << endl;
	}
};
class Device :public Base
{
public:
	Device()
	{
		cout << "Build a new Device" << endl;
	}
	 ~Device()
	{
		cout << "Delete something  in Device" << endl;
	}
};

int main()
{
	Base* p = new Device;
	delete p;
	return 0;
}

对比发现:

               在继承体系下,基类析构函数不是虚函数时,不会自动调用派生类析构函数,可能会造成内存泄漏。

               也就是说,非虚析构函数时,编译器只会去看p的类型,显然是基类类型,所以直接调基类析构函数。

               基类析构函数是虚函数时,会自动调用派生类的析构函数。

               虚析构函数时,编译器只会去看p的对象,显然是派生类,所以先调派生类析构,再调基类析构。

5,内联函数不能被声明 为虚函数 

               内联函数会在编译时在函数调用的地方展开,所以不具有函数指针,但是虚函数时通过函数指针调用的。

6,友元函数不能是虚函数

         友元函数不是类的成员函数。

五,那些函数不能被继承

1,构造函数

2,析构函数

3,拷贝构造函数

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值