码迷,mamicode.com
首页 > 编程语言 > 详细

C++ 面向对象编程

时间:2015-02-04 16:44:44      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:c++   面向对象   

  1. 面向对象编程基于三个基本概念:数据抽象、继承和动态绑定。在C++中,用类进行数据抽象,用类派生从一个类继承另一个类:派生类继承基类的成员。动态绑定使编译器能够在运行时决定是使用基类中定义的函数还是派生类中定义的函数。
  2. c++中,多态性仅用于通过继承而相关联的类型的引用或指针
  3. c++中,基类必须指出希望派生类重定义哪些函数,定义为virtual的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。
  4. 除了构造函数外,任意非static成员函数都可以是虚函数。保留字只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上。
  5. 派生类只能通过派生类对象访问其基类的protected成员,派生类对其基类类型对象的protected成员没有特殊访问权限。
  6. 派生类中虚函数的声明必须与基类中的定义完全匹配,但有一个例外:返回对基类的引用(或指针)的虚函数。派生类中的虚函数可以返回基类函数所返回类型的派生类的引用(或指针)。
  7. 一旦函数在基类中声明为虚函数,它就一直为虚函数,派生类无法改变改该函数为虚函数这一事实。派生类重定义虚函数时,可以使用virtual保留字,但不是必须的。
  8. 因为每个派生类对象都有基类部分,类可以访问其基类的public和protected成员,就好像那些成员是派生类自己的成员一样。
  9. c++中的函数调用默认不使用动态绑定。要触发动态绑定,必须满足两个条件:第一,只有指定为虚函数的成员函数才能进行动态绑定,成员函数默认为非虚函数,非虚函数不进行动态绑定;第二,必须通过基类类型的引用或指针进行函数调用。
  10. 只有通过引用或指针调用,虚函数才在运行时确定。只有在这些情况下,直到运行时才知道对象的动态类型。
  11. 派生类虚函数调用基类版本时,必须显示使用作用域操作符。如果派生类函数忽略了这样做,则函数调用会在运行时确定并且将是自身调用,从而导致无穷递归。
  12. public派生类继承基类的接口,它具有与基类相同的接口,设计良好的类层次中,public派生类的对象可以用在任何需要基类对象的地方。
  13. 使用private或protected派生的类不继承基类的接口,相反,这些派生通常称为实现继承。派生类在实现中使用被继承类但继承基类的部分并未成为其接口的一部分。
  14. 派生类可以恢复继承成员的访问级别,但不能使访问级别比基类中原来指定的更严格或更宽松
  15. 已定义的类才可以用作基类。这一限制的原因:每个派生类包含并且可以访问其基类的成员,为了使用这些成员,派生类必须知道它们是什么。这一规则暗示着不能从类自身派生出一个类。
  16. 如果需要声明一个派生类,则声明包含声明但不包含派生列表。像这样是错误的:class A:class B;
  17. 非虚函数总是在编译时根据调用该函数的对象、引用或指针的类型而确定
  18. 在某些情况下,希望覆盖虚函数机制并强制函数调用使用虚函数的特定版本,这时可以使用作用域操作符,只有成员函数中的代码才应该使用作用域操作符覆盖虚函数机制
  19. 友元关系不能继承
  20. 如果基类定义了static成员,则整个继承层次中只有一个这样的成员。无论从基类派生出多少派生类,每个static成员只有一个实例。static成员遵循常规访问控制:如果成员在基类中为private,则派生类不能访问它。假定可以访问成员,则既可以通过基类访问static成员,也可以通过派生类访问static成员。
  21. 如果有一个派生类型的对象,则可以使用它的地址对基类类型的指针进行复制或者初始化。同样,可以使用派生类型的引用或对象初始化基类类型的引用。严格来说,对对象没有类似的转换。编译器不会自动将派生类型对象转换为基类类型对象,但是,一般可以使用派生类型对象对基类对象进行复制或初始化(实际上是在调用函数实现的:初始化时调用构造函数,赋值时调用赋值操作符,因为存在派生类引用到基类引用的转换,那么直接就可以调用那个具有基类类型的(const)引用的复制构造函数)。
  22. 像继承的成员函数一样,从派生类到基类的转换可能是也可能不是可访问的。转换是否可访问取决于在派生类列表中指定的访问标号。如果是public继承,则用户代码和后代类都可以使用派生类到基类的转换。如果类是使用private或protected继承派生的,则用户代码不能将派生类型对象转换为基类对象。
  23. 从基类到派生类的自动转换是不存在的。需要派生类对象时不能使用基类对象,有时更令人惊讶的是,甚至当基类指针或引用实际绑定到派生类对象时,从基类到派生类的转换也存在限制。因为编译器无法知道转换是否在运行时是安全的,编译器确定转换是否合法,只看静态类型。
  24. 构造函数和复制控制成员不能继承,每个类定义自己的构造函数和复制控制成员。像任何类一样,如果类不定义自己的默认构造函数和复制控制成员,就将使用合成版本。
  25. 派生类的构造函数受继承关系的影响,每个派生类构造函数除了初始化自己的数据成员之外,还要初始化基类
  26. 构造函数初始化列表为类的基类和成员提供初始值,它并不指定初始化的执行次序。首先初始化基类,然后根据声明次序初始化派生类的成员
  27. 如果派生类定义了自己的复制构造函数,该复制构造函数一般应显示使用基类复制构造函数初始化对象的基类部分。
  28. 赋值操作符通常与复制构造函数类似:如果派生类定义了自己的赋值操作符,则该操作符必须对基类部分进行显示赋值。
  29. 析构函数的工作与复制构造函数和复制操作符不同:派生类析构函数不负责撤销基类对象的成员。编译器总是显示调用派生类对象基类部分的析构函数。每个析构函数只负责清除自己的成员:对象的撤销顺序与构造顺序相反:首先运行派生类析构函数,然后按继承层次一次向上调用各基类析构函数
  30. 自动调用基类部分的析构函数对基类的设计有重要影响。删除指向动态分配对象的指针时,需要运行析构函数在释放对象的内存之前清除对象。处理继承层次中的对象时,指针的静态类型可能与被删除对象的动态类型不同,可能会删除实际指向派生类对象的基类类型指针。如果删除基类指针,则需要运行基类析构函数并清除基类的成员,如果对象实际是派生类型的,则没有定义该行为。要保证运行适当的析构函数,基类中的析构函数必须为虚函数,如果析构函数为虚函数,那么通过指针调用时,运行哪个析构函数将因指针所指对象类型的不同而不同。像其他虚函数一样,析构函数的虚函数性质都将继承。因此,如果层次中根类的析构函数为虚函数,则派生类析构函数也将是虚函数,无论派生类显示定义析构函数还是使用合成析构函数,派生类析构函数都是虚函数。
    如果一个派生类对象使用new来分配,并且通过一个指向它的基类的指针来控制,那么它经常通过一个指向它的基类的指针来删除它(如果基类没有虚析构函数,结果将是不确定的,实际发生时,派生类的析构函数永远不会被调用)。
    基类有虚析构函数的话,最底层的派生类的析构函数最先被调用,然后各个基类的析构函数被调用。
  31. 即使析构函数没有工作要做,继承层次的根类也应该定义一个虚析构函数
  32. 每个类都保持着自己的作用域,在该作用域中定义了成员的名字。在继承情况下,派生类的作用域嵌套在基类作用域中。如果不能在派生类作用域中确定名字,就在外围基类作用域中查找该名字的定义。正是这种类作用域的层次嵌套使我们能够直接访问基类的成员,就好像这些成员是派生类成员一样。
  33. 与基类成员同名的派生类成员将屏蔽对基类成员的直接访问
  34. 在基类和派生类中使用统一名字的成员函数,其行为与数据成员一样:在派生类作用域中派生类成员将屏蔽基类成员。即使函数原型不同,基类成员也会被屏蔽
  35. 首先的一个事实是:在继承情况下,派生类的作用域嵌套在基类作用域中。其次局部作用域中声明的函数不会重载全局作用于中定义的函数,那么同样,派生类中定义的函数也不重载基类中定义的成员。通过派生类对象调用函数时,实参必须与派生类中定义的版本相匹配,只有在派生类根本没有定义该函数时,才考虑基类函数。
  36. 像其他任意函数一样,成员函数(无论虚还是非虚)也可以重载。派生类可以重定义所继承的0个或多个版本,如果派生类重定义了重载成员,则通过派生类型只能访问派生类中重定义的那些成员。
  37. 如果派生类想通过自身类型使用所有的重载版本,则派生类必须要重定义所有重载版本,要么一个也不重定义。有时类需要仅仅重定义一个重载集中某些版本的行为,并且想要继承其他版本的含义,在这种情况下,为了重定义需要特化的某个版本而不得不重定义每一个基类版本,可能会令人厌烦。派生类可以不用重定义所继承的每一个基类版本,它可以为重载成员提供using声明。一个using声明之恩给你指定一个名字,不能指定形参表,因此,这样就把该函数的所有重载实例都加到了派生类的作用域中了,接下来,派生类只需要重定义本类型确实必须定义的那些函数,对其他版本可以用继承的定义。
  38. 将函数定义为纯虚能够说明,该函数为后代类型提供了可以覆盖的接口,但是这个类中的版本绝不会调用。重要的是,用户将不能创建拥有纯虚函数声明类的对象。这种类就叫做抽象基类。
  39. 句柄类经常需要在不知道对象的确切类型时分配已知对象的新副本,要实现接受X类型的对象的构造函数,必须首先解决一个问题:我们不知道给予构造函数的对象的实际类型,他可能是X,也有可能是X的子类,为了解决这个问题,通用办法是定义虚操作进行复制,我们称之为clone

C++ 面向对象编程

标签:c++   面向对象   

原文地址:http://blog.csdn.net/wdkirchhoff/article/details/43486289

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!