360面试小结

一、struct和class的差别

C++中的struct对C中的struct进行了扩充。它已经不再仅仅是一个包括不同数据类型的数据结构了。它已经获取了太多的功能。
struct能包括成员函数吗? 能。struct能继承吗? 能。struct能实现多态吗? 能。

struct差点儿和class拥有一样的功能。

最本质的一个差别就是默认的訪问控制: 

默认的继承訪问权限

struct是public的,class是private的。struct和class能够相互继承。
你能够写例如以下的代码:
struct A
{
  char a;
};
struct B : A
{
  char b;
};

这个时候B是public继承A的。

假设都将上面的struct改成class,那么B是private继承A的。这就是默认的继承訪问权限。 

所以我们在平时写类继承的时候,一般会这样写:
class B : public A

就是为了指明是public继承。而不是用默认的private继承。

 

当然。究竟默认是public继承还是private继承取决于子类而不是基类

我的意思是。struct能够继承class,相同class也能够继承struct。那么默认的继承訪问权限是看子类究竟是用的struct还是class。

例如以下:

struct A{}。

class B : A{};     // private继承
struct C : B{}; // public继承

 

但我上面却没实用“唯一”。而是说的“最本质”,那是由于,它们确实还有还有一个差别。尽管那个差别我们平时可能非常少涉及。

那就是:“class”这个keyword还用于定义模板參数。就像“typename”。但keyword“struct”不用于定义模板參数。

这一点在Stanley B.Lippman写的Inside the C++ Object Model有过说明。 


还有默认数据的訪问权限,struct中的成员默认是public,外部可訪问。class中的成员变量默认是private。外部是不能直接訪问的。正通过公有成员函数訪问和改动。


二、new和malloc的差别

1.malloc与free是C++/C语言的标准库函数。new/delete是C++的运算符。它们都可用于申请动态内存和释放内存

2.对于非内部数据类型的对象而言。光用maloc/free无法满足动态对象的要求。对象在创建的同一时候要自己主动运行构造函数。对象在消亡之前要自己主动运行析构函数。由malloc/free是库函数而不是运算符,不在编译器控制权限之内,不可以把运行构造函数和析构函数的任务强加于malloc/free。

3.因此C++语言须要一个能完毕动态内存分配和初始化工作的运算符new。以一个能完毕清理与释放内存工作的运算符delete。注意new/delete不是库函数。 
4.C++程序常常要调用C函数,而C程序仅仅能用malloc/free管理动态内存。 
5.new能够觉得是malloc加构造函数的运行。new出来的指针是直接带类型信息的。而malloc返回的都是void*指针new/delete在实现上事实上调用了malloc,free函数。能够把其看成是malloc加上构造函数。

6.new建立的对象你能够把它当成一个普通的对象,用成员函数訪问。不要直接訪问它的地址空间;malloc分配的是一块内存区域,就用指针訪问好了,并且还能够在里面移动指针。

7.new 建立的是一个对象;malloc分配的是一块内存.


三、const的使用方法

const int * const ptr;    // 这个用得最多。两个const不解释

const douvle data = 3.1415;

类成员函数中const的使用一般放在函数体后。形如:void fun() const; 
不论什么不会改动数据成员的函数都因该声明为const类型。

假设在编写const成员函数时,不慎改动了数据成员,或者调用了其它非const成员函数,编译器将报错。这大大提高了程序的健壮性。

const成员变量仅仅对某个对象而言是常量。对于整个类来说是能够变化不同的。每一个生成的对象能够不同。用成员列表进行初始化


四、多态中析构函数能够不是虚么

基类的指针指向派生类对象。并用基类的指针删除派生类对象。这样会造成局部释放,内存泄露。

析构函数的工作方式是:最底层的派生类的析构函数最先被调用。然后调用每个基类的析构函数
由于在C++中,当一个派生类对象通过使用一个基类指针删除,而这个基类有一个非虚的析构函数,则结果是没有定义的。

执行时比較有代表性的后果是对象的派生部分不会被销毁。然而,基类部分非常可能已被销毁,这就导致了一个古怪的“部分析构”对象,这是一个泄漏资源。排除这个问题非常easy:给基类一个虚析构函数。于是,删除一个派生类对象的时候就有了你所期望的正确行为。将销毁整个对象。包含所有的派生类部分。

可是,一般假设不做基类的类的析构函数一般不声明为虚函数。由于虚函数的实现要求对象携带额外的信息,这些信息用于在执行时确定该对象应该调用哪一个虚函数。典型情况下,这一信息具有一种被称为 vptr(virtual table pointer,虚函数表指针)的指针的形式。vptr 指向一个被称为 vtbl(virtual table,虚函数表)的函数指针数组,每个包括虚函数的类都关联到 vtbl。当一个对象调用了虚函数,实际的被调用函数通过以下的步骤确定:找到对象的 vptr 指向的 vtbl。然后在 vtbl 中寻找合适的函数指针。这样子会使类所占用的内存添加。
定义纯虚析构函数(pure virtual destructor)。含有纯虚函数的类是ABC(Abstract Base Class)。


posted @ 2016-04-22 21:02  mengfanrong  阅读(370)  评论(0编辑  收藏  举报