0

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

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. 我怎么读第三 * thirdptr = new Third(); new 在“new int”时为 int 分配内存,但我不知道应该如何读取 new Third(); 因为它是构造函数

  2. 第二 * secondptr = thirdptr; / 第一 * firstptr = secondptr; 这两种说法太混乱了。任何人都可以用 & 运算符或与地址运算符相关的简单词语来解释它吗?我理解这个指针和继承的概念,但这部分太混乱了。

  3. 我应该如何从第二个示例中获得结果?我正在读的书说

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

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

这是翻译,可能不准确,但还是看不懂。如果您能帮助我,我将不胜感激!

4

2 回答 2

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

  2. Second * secondptr = thirdptr; / First * firstptr = secondptr; 所有三个变量都分配给同一个指针。假设thritptr等于 100。那么在这些语句的末尾,两者secondptr和都等于 100。firstptr所有三个指针都指向内存中的相同地址。但是,由于它们是不同的类型,因此编译器会以不同的方式解释它们

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

于 2013-03-21T03:35:56.023 回答
0

要回答你的第一个问题,new Third()在高层次上,做与new int. 如您所说,new int将为 a 分配内存,int左侧的指针将指向该内存。 new Third()Third对象分配内存,并使用Third类的默认构造函数Third(), 来初始化它。

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

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

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

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

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

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

至于你的第三个问题:

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

意味着编译器将根据内存中对象的实际类型而不是指向内存的指针的类型来决定调用哪个函数实例。因此,在您的示例中,您创建了一个类型为 的对象Third,并有三个指向它的指针,类型为First, Second, Third。但是,不管指针类型如何,因为Func是虚拟的,所以会执行Third的版本,Func因为内存中的对象是 类型的Third

于 2013-03-21T03:39:27.817 回答