C++沉思录

来源:互联网 发布:云计算就是服务器 编辑:程序博客网 时间:2024/04/28 18:34

1,如果派生类和基类有相同名字的变量,派生类会覆盖基类的变量吗?

class A { int i; }; 

class B : public class A { int i; };

不会覆盖,只会隐藏,sizeof(A) = 4, sizeof(B) = 8可以证明这一点,隐藏的意思是说通过派生类的对象或指针无法访问基类的变量,实际上,编译器可能会对类的member加上class名称,形成独一无二的命名,这个过程叫做name-mangling, 处理后class B变成:

class B { int i1A; int i1B; } ;

 

2.为什么static member function不能用const修饰

static void foo() const {} //Error

我们都知道,const函数不能改变对象,那么它是怎样做到这一点的呢?答案是用const修饰this指针,内部转化过程:

void foo() const { }  ----------------->void foo(const this) { }, 然而static函数没有this指针,所以也就没必要用const声明了。

 

3.一句话总结派生类如何利用基类:

我有的东西绝不跟你要,我没有的东西一定跟你要,如果你也没有,就算了。

 

4.哪些函数是虚函数(virtual function)?

(1).使用virtual关键字声明的: class A { virtual void foo() {} }; 这样的函数是virtual function

(2).从基类继承而来的,且重写(overrided)了:

class A { virtual void foo() {} };   class B : public class A { void foo() {} };

我们说Class B的foo()函数也是virtual function

(3).从基类继承而来的,没有重写:

class A { virtual void foo() {} };   class B : public class A {  };

虽然class B没有foo()的定义,但class B有一个virtual function,那就是A::foo(),因为它是从class A继承而来的。

(4)基类的destructor是virtual的

class A { virtual ~A() {} };   class B : public class A { ~B() {} };

我们说class B的destructor也是virtual function

对于所有上述virtual function,编译器都会把它们的首地址保存在一个Virtual Table里面。

注意构造函数不能是virtual functjion,从实现上来说,调用virtualfunction需要保证设置好vptr,而调用造函数时这个vptr根本还没初始化,也就不能使用,所以不能把构造函数声明为virtual.从实际意义来说,调用构造函数意味着想要创建一个类的对象,这个类是确定的,所以它所调用的构造函数也是确定的,故没必要把构造函数变为virtual。

 

4。满足哪些条件才会重载(overrid)基类的函数

C++标准规定,只有函数名,参数列,返回值类型都相同,才会重写,下列函数都会重载:

void func()-------void func()

virtual void func() ------void func()

void func() ---------virtual func()

virtuan void func() --------virtual void func()

注意这里的返回值支持多态,也就是如果class Derived : public Base那么这个函数也会重写

Base *clone() ---------Derived *clone()

 

5.以下两个函数有什么区别?

int k = 5;

int *j = k;

void func1( int * i) {}

void func2( int * & i) {}

本质上,两个函数的实参都是一个变量的地址,但有一点微小的却别。

func1的形参类型为int *,那么实参可以为指针变量,也可以为int变量的地址,所以有两种调用方式:

func1( &k );

func1( j );

func2的形参为指针的引用,那么实参必须是指针变量,所以只能这样调用:

func2( j )

 

6。友元函数的作用是什么?

大多数时候都会把类的data members声明为protected,这样的封装符合面向对象的设计原则,但有些时候我们会很想访问一个对象的protected成员,可以在类里面插入一个友元函数,把它的参数设为类的引用,然后在类的外面定义它,通过参数--对象的引用来访问protected成员。