C/C++ Tips (2)

1、C++里的钻石结构

      class A { };
      class B : virtual public A  { };
      class C : virtual public A { };
      class D : public B, public C { };

2、long和float都是用四个字节表示

3、关键字volatile的作用

        一个定义为volatile的变量是说这变量可能会被意想不到的改变,这样,编译器就不会去假设这个变量的值了。精确的说就是,优化器在用到这个变量时必须每次都小心的重新读取这个变量的值,而不是保存在寄存器里的备份。

4、抽象类和接口的区别

        抽象类是特殊的类,只是不能被实例化(将定义了纯虚函数的类称为抽象类);除此之外,抽象类具有类的其它特性;重要的是抽象类可以包含抽象类和抽象方法,这是普通类所不能的,但同时也可以包含普通的方法。抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们。虽然不能定义抽象类的实例,但是可以定义它的指针,这正是抽象类实现接口的重点所在。

       接口是一个概念,它在C++中用抽象类实现,在C#和Java中用interface来实现。

       接口是引用类型的,类似于类,和抽象类的相似之处有三点。

               1)不能实例化

               2)包含未实现的方法和声明

               3)派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法,包括其它成员)

        另外,接口有如下特性:

        接口除了可以包含方法之外,还可以包含属性、索引器、事件,而这些成员都被定义为公有的。除此之外,不能包含其它的任何成员,例如:常量、域、构造函数、析构函数,静态成员。

5、sizeof和strlen的区别

       sizeof是一种单目运算符,而strlen是一个函数。

       sizeof的操作数可以是数据类型、函数、变量、表达式

       strlen的应用则不像sizeof那么广泛,参数必须是char *型的指针

6、什么是野指针,什么情况下会产生野指针,如何避免?

       野指针是指向不可用内存区域的指针。通常对野指针进行操作的话,会产生不可预知的错误。

       野指针的产生有三种情况:

                 1)指针变量未被初始化

                 2)动态内存中指针被free或delete释放后没有被置为null

                 3)指针操作超越了变量的作用范围

      避免:我们需要将指针初始化为NULL,用完后也为其赋值NULL

                  拷贝构造时防止浅拷贝

7、面向对象的三个要素五个原则

     三要素:继承封装多态

         封装:将抽象得到的数据和方法相结合,形成一个有机整体,使用者不必了解具体的实现细节,而只要通过外部接口,一特定的访问权限来使用类的成员

         继承:继承可以使子类具有父类的各种属性和方法,而不需要编写相同的代码

         多态:不同的对象调用相同的函数会产生不同的效果,允许将子类类型的指针赋给父类类型的指针

    五元则:单一职责原则

                         应该有且仅有一个原因引起类的变更 

                   开放封闭原则

                         对扩展开放,对修改封闭

                   里氏替换原则

                        子类可以扩展父类的功能,但不能改变父类的功能

                   依赖倒置原则

                        对抽象进行编程,不要对实现进行编程,这样就降低了业务与实现模块间的耦合

                   接口隔离原则 

                       使用多个专门的接口总比使用一个单一的接口好

8、与类相关的sizeof操作

定义一个 空的类,没有任何的成员变量和成员函数,对该类型求sieof,得到的结果是多少?

答案是1,空类型的实例中不包含任何信息,本来求sizeof应该是0,但是当我们声明该类型的实例的时候,它必须在内存中占有一定的空间,否则无法使用这些实例。至于占用多少内存,由编译器决定。Visual Studio中每个空类型的实例占用1字节的空间。

如果在该类型中添加一个构造函数和析构函数,再对该类型求sizeof,得到的结果又是多少?

和前面一样,还是1。调用构造函数和析构函数只需要知道函数的地址即可,而这些函数的地址只与类型相关,而与类型的实例无关,编译器也不会因为这两个函数而在实例内添加额外的信息。

那如果把析构函数标记为 虚函数呢?

C++的编译器一旦发现一个类型中有虚拟函数,就会为该类型生成虚函数表,并在该类型的每一个实例中添加一个指向虚函数表的指针。在32位机器上,一个指针占4个字节的空间。

9、不允许复制构造函数传值

如果允许复制构造函数传值,就会在复制构造函数内调用复制构造函数,就会形成无休止的递归调用从而导致栈溢出






          


   

   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值