c++期末考试学习资料
C++ Final exam study material
我一直在做这个问题,为我即将到来的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;
}
,其输出为:
A
B default
this.i 1
1 in B
我明白,A
被打印是从超类A
调用B
的构造函数,我明白,使指针*pa
点在&b
使其访问foo
的基类方法,但它是如何在B::print()
中打印值而不是A::print()
?
这是因为您在b中重写了print(),并且由于foo()在类A中未定义为虚函数,因此调用了类A中的foo()。
由于B
派生自A
,因此每个B
都是和A
。因此,pa
可以指向A
类型或任何派生类型的对象。但是对象的类型没有改变,所以b
仍然是B
类型,并且行为也是这样。唯一的限制是,由于它是由指向A
的指针引用的,因此您只能引用在基类A
中声明的方法和成员变量。
关于为什么 c++以这种方式工作的解释,请查看vtable
s的讨论。
virtual void print()
函数前面的虚字使多态发挥了它的魔力。当派生类实现了在基类中声明为虚函数的函数时,派生类的实例将调用该函数,而不是调用基类函数。
您创建了派生类B的实例,B有一个名为print()的成员函数,它将被调用。
pa->foo();
和
pa->print();
是由一个简单的事实引起的:
指针的类型指示编译器如何解释在特定地址找到的内存,以及该解释应该跨越多少内存
,出自书 c++对象模型内部。
换句话说,当编译器试图翻译pa->foo()
这行代码时,他只知道pa是a类的指针,而foo是a类的函数。虽然我们实际上知道pa指向B类的内存块,但编译器不知道也不可能知道这个事实。他只是将pa解析为a类的指针,并找到a对函数foo的定义。pa->print()
的神奇之处在于c++的虚函数实现。对于普通函数,编译器只解析它的名称并跳转到该函数的起始地址。然而,对于虚函数,编译器将首先从指针pa所指向的内存中查找vptr指针,并解析vptr以查找print函数的正确定义。因为这次编译器从内存中读取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
B default
42
42, 43
顺便说一下,虚函数机制只对指针或引用有效,因为对于对象a, A.print()
必须解析为a类内存块中的vptr,这是a的print函数
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 我是 c++ 的新手.学习基本知识后,我想做井字游戏.对于印刷板,我在下面写代码,但它显示错误
- 神经网络不学习.卡在50%
- 在学习数据结构之前对STL有一个了解是好的吗?
- 如何将经过训练的机器学习模型保存在python中并将其加载到C++中进行预测?
- 学习 c++,编译错误"no matching function for call"
- 学习数据结构和算法的简单方法
- 我正在尝试学习如何在 c++ 中传递指针,但出现错误:没有用于调用"test"的匹配函数。我做错了什么?
- 学习嵌套循环C++与示例混淆
- 从书本中学习C++无法使该程序与类一起工作
- 我的期末考试遇到了麻烦.代码不断循环回到我的订购菜单,不会显示我的总价
- 刚开始学习C++
- 学习C++并在早期示例中遇到错误(在非静态数据成员之前需要构造函数)
- 学习时空复杂性时语句XYZ的含义是什么?
- Q学习扫雷行为
- 我可以在没有C++的情况下学习 Win32 API(仅使用 C)吗?
- 学习C,我的编译器已经知道bool(Visual Studio 2017)
- 我正在学习C++,我不能使用指针访问参考吗?(举个例子)
- 我正在学习考试,我需要帮助!C++
- c++期末考试学习资料