c++基础知识整理

来源:互联网 发布:网络提速 编辑:程序博客网 时间:2024/04/30 02:38

const关键字

const int*p;  
int const *q;  

指针所指向的内存不能被修改,但指针可以指向另一个内存
int * const r= &n;

int类型的const指针应该这样声明。指针所指向的内存可以被修改,但指针不能指向另一个内存
const在函数声明中的含义:

constint& SetPoint(const int& param) const
第一个const:
函数的返回值限定为const,即返回值不能被修改。const int a=SetPoint(...)  a在此之后便不能被修改。
第二个const:
指函数的形参为const类型,函数体内不能被修改.
第三个const:
表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变。


类的private/protected/public属性

1、类的成员如果没有指定访问域,默认是private的。

2、标识符protected 与 private类似,它们的唯一区别在继承时才表现出来。当定义一个子类的时候,基类的protected 成员可以被子类的其它成员所使用,然而private 成员就不可以。

3、public/protected/private继承的区别:
(1)public继承:父类的public依然是public,protected依然是protected,private不可访问;
(2)protected继承:父类的public称为protected,protected称为private;
(3)private继承:父类的所有成员全部变成private。


sizeof一个空类等于多少?

sizeof一个空类返回1。所谓类的实例化就是在内存中分配一块地址,每个实例在内存中都有独一无二的地址。同样空类也会被实例化,所以编译器会 给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。C++编译器不允许对象为零长度。试想一个长度为0 的对象在内存中怎么存放?怎么获取它的地址?为了避免这种情况,C++强制给这种类插入一个缺省成员,长度为1。如果有自定义的变量,变量将取代这个缺省 成员。


继承或多重继承情况下构造函数的调用顺序

(1)如果声明为Derive: public Super1, publicSuper2{AnotherClass m_obj;}; 构造函数的调用顺序是:Super1, Super2, AnotherClass,Derive.
(2)如果父类有默认构造函数,或没有参数的构造函数,不需要在子类的构造函数定义中显式调用父类构造函数,否则需要调用。成员对象也是一样道理。以上面的例子说明,Derive的构造函数写法是:
Derive(int i): Super1(i), Super2(i), m_obj(1){...}
注意,成员对象初始化时应该指明对象名称,而不是类名。

析构函数的调用顺序应该是依次反过来的。


虚函数、纯虚函数和抽象类、虚析构函数

 

虚函数的作用和运行原理

(1)多态是面向对象编程中的核心概念,就是说一个基类类型的指针实际上可能指向的是一个子类对象。只有在运行时才能根据实际情况来决定执行哪个函 数,也就是动态联编。和动态联编对应的是静态联编,也就是说在编译时就决定了调用哪个函数。为了实现动态联编,必须将父类的函数声明为virtual。如果没有声明为virtual,可能得到的结果不是预期中的。
对于析构函数而言,虚函数保证子类和父类的析构函数都会被执行。

(2)对于包含了至少一个虚函数的类(或其父类包含虚函数),编译器需要为这个类增加4个字节,用来保存指向虚函数表VTABLE的指针。

 

 

什么情况下需要指定析构函数为virtual?

(1)析构函数不一定需要定义为虚函数,只有当这个类要作为其他类的父类使用时,才需要定义为虚函数。如果父类的析构函数没有定义为虚函数,则子类对象销毁时,父类析构函数不会被调用。
(2)对于一个抽象类,析构函数可以被定义为纯虚的。
(3)父类和子类之间的虚函数动态联编不会因为private发生影响。
(4)一个类的虚函数在它自己的构造函数和析构函数中被调用的时候,它们就变成普通函数了,不“虚”了。也就是说不能在构造函数和析构函数中让自己“多态”。
(5)在虚函数和纯虚函数的定义中不能有static标识符,原因很简单,被static修饰的函数在编译时候要求前期bind,然而虚函数却是动态绑定(run-time bind),而且被两者修饰的函数生命周期(life recycle)也不一样。

友元可以实现外部对private和protected成员的访问。有两种实现:
(1)友元函数。语法:在函数声明前加上friend。友元函数并不是类的成员函数,实现函数体或调用函数时不加ClassName::。
(2)友元类。在类的声明中加入:friend class VisitorClass;
友元不会被子类继承。


 引用和指针

  相同点:

  1. 都是地址的概念;

  指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。

  区别:

  1. 指针是一个实体,而引用仅是个别名;

  2. 引用使用时无需解引用(*),指针需要解引用;

  3. 引用只能在定义时被初始化一次,之后不可变;指针可变;

  引用"从一而终" ^_^

  4. 引用没有 const,指针有 const,const 的指针不可变;

  5. 引用不能为空,指针可以为空;

  6. "sizeof 引用"得到的是所指向的变量(对象)的大小,而"sizeof 指针"得到的是指针本身(所指向的变量或对象的地址)的大小;

  typeid(T) == typeid(T&) 恒为真,sizeof(T) == sizeof(T&) 恒为真,

  但是当引用作为成员时,其占用空间与指针相同(没找到标准的规定)。

  7. 指针和引用的自增(++)运算意义不一样;