对象类型在编译时怎么可能是未知的
How can an object type be unknown at compile time?
我目前正在学习动态绑定和虚拟函数。这来自Accelerated C++,第13章:
[…]我们希望在运行时做出决定。也就是说,我们想要系统根据实际类型运行正确的功能传递给函数的对象,只有在运行时才知道。
我不理解在编译时对象的类型可能是未知的。从源代码来看,这不是很明显吗?
一点也不。考虑这个例子:
struct A {
virtual void f() = 0;
};
struct B : A {
virtual void f() { std::cerr << "In B::f()n"; }
};
struct C : A {
virtual void f() { std::cerr << "In C::f()n"; }
};
static void f(A &a)
{
a.f(); // How do we know which function to call at compile time?
}
int main(int,char**)
{
B b;
C c;
f(b);
f(c);
}
当编译全局函数f
时,无法知道它应该调用哪个函数。事实上,它每次都需要调用不同的函数。第一次用f(b)
调用它时,需要调用B::f()
,第二次用f(c)
调用它时需要调用C::f()
。
C++有一个指针的概念,其中变量只包含一个指向实际对象的"句柄"。实际对象的类型在编译时是未知的,只有在运行时才知道。示例:
#include <iostream>
#include <memory>
class Greeter {
public:
virtual void greet() = 0;
};
class HelloWorld : public Greeter {
public:
void greet() {std::cout << "Hello, world!n";}
};
class GoodbyeWorld : public Greeter {
public:
void greet() {std::cout << "Goodbye, world!n";}
};
int main() {
std::unique_ptr<Greeter> greeter(new HelloWorld);
greeter->greet(); // prints "Hello, world!"
greeter.reset(new GoodbyeWorld);
greeter->greet(); // prints "Goodbye, world!"
}
另请参阅:Vaughn Cato的答案,它使用引用(这是保持对象句柄的另一种方式)。
假设您有一个指向基类的指针,指向派生对象
Base *pBase = new Derived;
// During compilation time, compiler looks for the method CallMe() in base class
// if defined in class Base, compiler is happy, no error
// But when you run it, the method call gets dynamically mapped to Derived::CallMe()
// ** provided CallMe() is virtual method in Base and derived class overrides it.
pBase->CallMe(); // the actual object type is known only during run-time.
相关文章:
- 头文件可以在主类中运行.这怎么可能?
- 怎么可能只让设备使用 pjsua2 捕获或播放
- std::lock_guard 怎么可能比 std::mutex::lock() 更快?
- 怎么可能写 f( *this, std::forward<Args>(args)... ) 而 f 只用 F f 声明;
- 在QT C++编辑Qtable模型数据时,我需要得到一个小盒子,我需要显示编辑文本,这怎么可能?
- 在给定相同的输入的情况下,某些代码怎么可能花费更多时间来运行,这似乎只是因为它处于循环中?
- 答案怎么可能是433?
- 八进制文字怎么可能是负数?
- 我们可以在整数类型的双指针中分配2D整数数组的地址吗?怎么可能
- 我怎么可能从尚未定义某些成员方法的类创建实例?(C++)
- 使用 stl 迭代器封装向量是否很好?如果是?怎么可能呢?
- 几个比较怎么可能比一些计算慢
- 我的 Cuda 矢量怎么可能在填充后是空的
- 怎么可能有两个同名的变量——一个是全局变量,另一个是局部变量
- 奇怪的交叉播.这怎么可能
- 一个变量怎么可能既是constexpr又不是constexpr
- 如果方法私有,是否可以从 main 调用该方法?如果不是,怎么可能
- ANSI到Unicode或向后转换:怎么可能?
- std::unique_ptr怎么可能没有大小开销
- 对象类型在编译时怎么可能是未知的