Essential C++笔记(面向对象编程风格)

实际编程中出现的问题及其总结:

  • 抽象基类中每一个纯虚函数在派生类中需要被重载,如果存在某一个纯虚函数未被重载,那么派生类由于继承了该纯虚函数导致派生类也为抽象类,不能被初始化;
  • 定义抽象基类的时候想清楚哪些函数可以被声明为const,哪些函数的参数可以被声明为const.

1.面向对象编程的几个特点:

  • In an object-oriented program, we indirectly manipulate the class objects of our application
    through a pointer or reference of an abstract base class rather than directly manipulate the actual
    derived class objects
    of our application. This allows us to add or remove a derived class without
    the need for any modification to our existing program.
  • The second unique aspect of object-oriented programming is polymorphism: the ability of a base
    class pointer or reference to refer transparently to any of its derived class objects
    .
  • Dynamic binding is a third aspect of object-oriented programming.

2.决议(resolve)在什么时候进行

By default, a member function is resolved statically at compile-time. To have a member function
resolved dynamically during run-time, we preface its declaration with the virtual keyword.

3.设计抽象基类的步骤

  • identify the set of operations common to its children.
  • identify which operations are type dependent— that is, which operations require separate implementations based on the derived class type.
  • identify the access level of each operation.(声明为protected的函数可被派生类调用,不能在外部调用)

4.纯虚函数pure virtual function,对于在抽象基类中实现没有实际意义的函数可以声明为纯虚函数

virtual void gen_elems(int pos) = 0;

5.定义了虚函数的基类要将析构函数声明为virtual

As a general rule, a base class that defines one or more virtual functions should always
define a virtual destructor.

(实际实验发现析构函数不声明为virtual也能正常工作)

6.在派生类中定义,而未在基类中定义的数据成员和成员函数不能通过基类的指针或者引用调用。

7.在基类中声明为virtual的函数在其派生类中自动成为virtual函数,即使没有加virtual关键字

8.对于在派生类和基类中同名的member,基类中该member自动隐藏,也就是说在派生类内对该member的引用都被决议到派生类自身的该member,除非使用class scope operator才能调用基类的该member.

Whenever a member of the derived class reuses the name of an inherited base class member, the
base class member becomes lexically hidden within the derived class. That is, each use of the
name within the derived class resolves to the derived class member. To access the base class
member within the derived class, we must qualify its reference with the class scope operator of the
base class.

9.在派生类中重载基类虚函数要求函数原型一致,否则相当于重新定义了一个同名函数

If we choose to override the base class instance, the prototype of the derived class instance must
match the base class protoype exactly: the parameter list and the return type and whether the
virtual function is const or non-const
.

但是有一个例外,假如基类虚函数返回值类型是指向基类的指针,则在派生类中重载时返回值类型可以是基类的任何派生类类型

10.虚函数的静态决议(static resolution)

  • 如果在基类构造函数或者析构函数中调用派生类的成员函数,则由于派生类中data member尚未被分配内存或者内存已经释放,会静态决议为调用基类的虚函数。
  • 当我们使用基类的对象而不是基类的指针或者引用时,不会调用派生类的虚拟函数

 int main()
{
AudioBook iWish("Her Pride of 10",
"Stanley Lippman", "Jeremy Irons");
gen_elems(iWish, &iWish, iWish);
// ...
}
only the base class LibMat portion of iWish can be copied into the memory reserved for object;
Tthe Book and AudioBook subobjects are sliced off. pointer and reference are initialized
simply with the address of the original iWish object.

11.执行期的型别判定机制(run-time type identification)

#include <typeinfo>
inline const char* num_sequence::
what_am_i() const
{ return typeid(*this).name(); }

The typeid operator returns a type_info class object. This object stores type information. There is one associated with
each polymorphic class, such as the Fibonacci and Pell derived classes. name() returns a const
char* representation of the class name.

猜你喜欢

转载自blog.csdn.net/zhuwj06/article/details/6315025
今日推荐