虚函数, - >运算符,继承SO CONFUSING

时间:2013-03-21 03:22:45

标签: c++ function pointers inheritance override

好的,这是一个让我如此困惑的简单例子......

class First { public: void Func() {cout<<"FirstFunc";} };
class Second : public First
    { public: void Func() {cout<<"SecondFunc";} };
class Third : public Second
    { public: void Func() {cout<<"ThirdFunc";} };

int main () {
   Third * thirdptr = new Third();
   Second * secondptr = thirdptr;
   First * firstptr = secondptr;

   firstptr->Func();  // prints out FirstFunc
   secondptr->Func();  // prints out SecondFunc
   thirdptr->Func();  // prints out ThirdFunc

   delete thirdptr;

这是虚拟功能

class First { public: virtual void Func() {cout<<"FirstFunc";} };
class Second : public First
    { public: virtual void Func() {cout<<"SecondFunc";} };
class Third : public Second
    { public: virtual void Func() {cout<<"ThirdFunc";} };

int main () {
   Third * thirdptr = new Third();
   Second * secondptr = thirdptr;
   First * firstptr = secondptr;

   firstptr->Func();  // prints out ThirdFunc
   secondptr->Func();  // prints out ThirdFunc
   thirdptr->Func();  // prints out ThirdFunc

   delete thirdptr;

好的,这是我的问题。

  1. 我如何阅读Third * thirdptr = new Third(); new在“new int”时为int分配内存 但我不知道我应该如何阅读新的Third();因为它是构造函数

  2. Second * secondptr = thirdptr; / First * firstptr = secondptr; 这两个陈述令人困惑。 任何人都可以用&amp;运算符或简单的单词将其与地址运算符相关联 我理解了这个指针和继承的概念,但这部分令人困惑。

  3. 我应该如何从第二个例子中得到结果? 我正在读的那本书正在说

  4. 为第一个例子 //关于指针算术运算的C ++编译器做出决定 //基于指针的类型,而不是指针实际指向

    的内容

    第二个例子 //虚拟功能:决定,而不是基于指针类型 //,根据指针实际指向的内容调用什么

    这是翻译,所以可能不准确,但仍然无法理解。 如果你能帮助我,我将非常感激!

2 个答案:

答案 0 :(得分:0)

  1. new Third()做了两件事。首先,它为Third对象分配内存,然后在Third上调用构造函数。您可以将语句视为两部分,new Third分配内存,()调用构造函数。

  2. Second * secondptr = thirdptr; / First * firstptr = secondptr;所有三个变量都分配给同一个指针。假设thritptr等于100.那么secondptrfirstptr在这些陈述的末尾将等于100。所有三个指针都指向内存中的相同地址。然而,由于它们是不同的类型,因此它们编译它们不同于它们

  3. 对于非虚函数,方法调用在编译时根据变量的类型进行解析。因此,在编译第一个代码firstptr时,类型为First*,因此编译器会生成对First::Func()的调用。对于虚函数,方法调用直到运行时才完全解析。编译器生成的代码将确定变量指向的实际类型并调用该函数。在第二个示例中,当程序运行时,firstpr->Func()它首先确定firstptr确实指向Thrird对象,因此它调用Third::Func()。这通常使用virtual function table

  4. 完成

答案 1 :(得分:0)

要回答您的第一个问题,new Third()在高级别上与new int做同样的事情。如上所述,new int将为int分配内存,左侧的指针将指向该内存。 new Third()Third对象分配内存,并使用ThirdThird()的默认构造函数对其进行初始化。

对于第二个问题,您正在创建三个指针并将它们全部指向同一个内存块。我相信由于继承,可以隐式地将每个指针类型转换为更高的类型(隐式转换意义没有显式指令,例如static_cast或C样式转换)。目测:

----
|  | <-- Some block of memory.
----

A -> ---- <-- A* aptr = new A();
     |  |
     ----

A -> ----
B -> |  | <-- B* bptr = aptr;
     ----

A -> ----
B -> |  |
C -> ---- <-- C* cptr = bptr;

注意所有三个指针都指向同一块内存。 (另请注意,指针都指向内存的 start - 完全相同的位置。上面描述的很难。)

至于你的第三个问题:

  

决定,不是基于指针类型,根据什么来调用什么   指针实际指向

表示编译器将根据内存中对象的实际类型决定调用哪个函数实例,而不是指向内存的指针类型。因此,在您的示例中,您创建了一个类型为Third的对象,并且有三个指针指向它,类型为FirstSecondThird。但是,无论指针类型如何,因为Func是虚拟的,所以Third的{​​{1}}版本被执行,因为内存中的对象是Func类型。