C++;期末考试学习材料 我一直在为准备我即将到来的C++期末考试做准备: // What gets printed? #include <iostream> using namespace std; class A { public: A(int a = 5) : i(a) { cout << "A" << endl; } void foo() { cout << "this.i " << i << endl; } virtual void print() const { cout << i << " in A" << endl; } protected: int i; }; class B : public A { public: B() : A(1) { cout << "B default" << endl; } void foo() { cout << i << " in B" << endl; } void print() const { cout << i << " in B" << endl; } }; int main() { A *pa; B b; pa=&b; pa->foo(); pa->print(); return 0; }

C++;期末考试学习材料 我一直在为准备我即将到来的C++期末考试做准备: // What gets printed? #include <iostream> using namespace std; class A { public: A(int a = 5) : i(a) { cout << "A" << endl; } void foo() { cout << "this.i " << i << endl; } virtual void print() const { cout << i << " in A" << endl; } protected: int i; }; class B : public A { public: B() : A(1) { cout << "B default" << endl; } void foo() { cout << i << " in B" << endl; } void print() const { cout << i << " in B" << endl; } }; int main() { A *pa; B b; pa=&b; pa->foo(); pa->print(); return 0; },c++,C++,我知道打印的A是从超类A调用B的构造函数得到的,而且我知道让指针*pa指向&B可以访问foo的基类方法,但是它是如何打印B::print()中的值的而不是A::print()?因为B是从A派生出来的,所以每个B都是A。因此,pa可以指向类型为A或任何派生类型的对象。但是对象的类型没有改变,因此b仍然是b类型,其行为也是如此。唯一的限制是,由于它被指向a的指针引用,因此只能引用在基类a中声明的方法和成员变量 < >解释C++为何这样工作,请查阅关于 VTAB< S.< /P> < P>的讨论,因

我知道打印的
A
是从超类
A
调用
B
的构造函数得到的,而且我知道让指针
*pa
指向
&B
可以访问
foo
的基类方法,但是它是如何打印
B::print()中的值的
而不是
A::print()

因为
B
是从
A
派生出来的,所以每个
B
都是
A
。因此,
pa
可以指向类型为
A
或任何派生类型的对象。但是对象的类型没有改变,因此
b
仍然是
b
类型,其行为也是如此。唯一的限制是,由于它被指向
a
的指针引用,因此只能引用在基类
a
中声明的方法和成员变量


< >解释C++为何这样工作,请查阅关于<代码> VTAB< <代码> S.< /P> < P>的讨论,因为代码> B/<代码>是从<代码> A < /COD>派生的,每个<代码> B<代码>是<代码> A<代码>。因此,
pa
可以指向类型为
A
或任何派生类型的对象。但是对象的类型没有改变,因此
b
仍然是
b
类型,其行为也是如此。唯一的限制是,由于它被指向
a
的指针引用,因此只能引用在基类
a
中声明的方法和成员变量


< >解释C++为什么这样工作,寻找一个关于<代码> vtabs>代码> S.< /P> < P>的原因,因为,在B中,您忽略了打印(),因为FoE()不被定义为类中的虚函数,因此,从A类中得到了FULL()。在类A中未定义为虚拟,因此调用了类A中的foo()

virtual void print()
函数前面的单词virtual使多态性发挥了神奇的作用。当派生类实现一个在基类中声明为虚拟的函数时,它将被调用,而不是派生类实例的基类函数

您创建了派生类B的一个实例,B有一个名为print()的成员函数,它将在那里被调用

函数前面的单词virtual使多态性发挥了神奇的作用。当派生类实现一个在基类中声明为虚拟的函数时,它将被调用,而不是派生类实例的基类函数


您创建了派生类B的一个实例,并且B有一个名为print()的成员函数,在那里它将被调用。

两者之间的区别

pa->foo();

原因很简单:

指针的类型指示编译器如何解释在特定地址找到的内存,以及解释应该跨越多少内存

,从C++内部的C++对象模型中。 换句话说,当编译器试图翻译这行代码

pa->foo()
时,他只知道pa是类a的指针,foo是类a的函数。虽然我们知道事实上pa指向类B的内存块,但编译器不知道也不可能知道这一事实。他只是将pa解析为类a的指针,然后找到a的函数foo的定义。然而, PAR>打印(<)/>代码的神奇之处在于C++的虚函数实现。对于普通函数,编译器只需解析其名称并跳转到该函数的起始地址。然而,对于虚拟函数,编译器将首先从指针pa指向的内存中找到vptr指针,并解析vptr以找到打印函数的正确定义。因为这次编译器从内存读取vptr,而内存实际上属于类B,所以将调用B的print。
下面是另一个例子来说明这一点:

// What gets printed?
#include <iostream>
using namespace std;
class A {
  public:
int b;
    A(int a = 5) : i(a) { 
      b = 42;
  cout << "A" << endl; 
    }
    void foo() { cout << "this.i " << i << endl; }
    virtual void print() const { cout << i << " in A" << endl; }
   protected:
     int i;
 };
 class B : public A {
   public:
 int b;
     B() : A(1) { 
       b = 43;
   cout << "B default" << endl; }
     void foo() { cout << i << " in B" << endl; }
     void print() const { cout << i << " in B" << endl; }
 };
 int main() {
   A *pa;
   B b;
   pa=&b;
   cout << pa->b << endl;
   cout << b.A::b << ", " << b.b << endl;
   //pa->foo();
   //pa->print();
   return 0;
 }

顺便说一句,虚拟函数机制只对指针或引用有效,因为对于对象a,
a.print()
必须解析为类a内存块中的vptr,该类内存块是a的打印函数

pa->foo();

原因很简单:

指针的类型指示编译器如何解释在特定地址找到的内存,以及解释应该跨越多少内存

,从C++内部的C++对象模型中。 换句话说,当编译器试图翻译这行代码

pa->foo()
时,他只知道pa是类a的指针,foo是类a的函数。虽然我们知道事实上pa指向类B的内存块,但编译器不知道也不可能知道这一事实。他只是将pa解析为类a的指针,然后找到a的函数foo的定义。然而, PAR>打印(<)/>代码的神奇之处在于C++的虚函数实现。对于普通函数,编译器只需解析其名称并跳转到该函数的起始地址。然而,对于虚拟函数,编译器将首先从指针pa指向的内存中找到vptr指针,并解析vptr以找到打印函数的正确定义。因为这次编译器从内存读取vptr,而内存实际上属于类B,所以将调用B的print。
下面是另一个例子来说明这一点:

// What gets printed?
#include <iostream>
using namespace std;
class A {
  public:
int b;
    A(int a = 5) : i(a) { 
      b = 42;
  cout << "A" << endl; 
    }
    void foo() { cout << "this.i " << i << endl; }
    virtual void print() const { cout << i << " in A" << endl; }
   protected:
     int i;
 };
 class B : public A {
   public:
 int b;
     B() : A(1) { 
       b = 43;
   cout << "B default" << endl; }
     void foo() { cout << i << " in B" << endl; }
     void print() const { cout << i << " in B" << endl; }
 };
 int main() {
   A *pa;
   B b;
   pa=&b;
   cout << pa->b << endl;
   cout << b.A::b << ", " << b.b << endl;
   //pa->foo();
   //pa->print();
   return 0;
 }

顺便说一句,虚拟函数机制只对指针或引用有效,因为对于对象a,
a.print()
必须解析为类a内存块中的vptr,该类内存块是a的打印函数

,因为这是多态性的全部要点(并非双关语)…我希望你没有按格式评分!因为这就是多态性的全部意义(没有双关语的意思)…我希望你没有按格式评分!VTABLE不是C++工作的原因,而是如何实现的。OP不需要了解任何关于vtables的信息就可以理解se
A
B default
42
42, 43