gpt4 book ai didi

c++ - 在父类指针映射中存储子类指针

转载 作者:搜寻专家 更新时间:2023-10-31 00:54:59 26 4
gpt4 key购买 nike

假设我有一个名为 Libitem 的父类和一个名为 Book 的子类。如果我将 Book 的指针存储在 Libitem 的指针映射中,当我尝试访问它时,我是否会得到 Book 的指针再次?像这样:

std::map<int, Libitem*> catalog;
Libitem* b = new Book();
catalog[1] = b;
Libitem* old_book = catalog[1]; //would old_book be a Book or a Libitem? In other word would it
//have all the function of a Book class?

最佳答案

你正在像这样检索你的对象:

Libitem* old_book = catalog[1];

有了它,编译器只知道您有一个名为 old_book 的变量,类型为指向 Libitem 的指针。如果您自己单独阅读该特定行,您会注意到,这是您和编译器在那一刻拥有的唯一信息。当你自己读到这一行的那一刻就是编译时间。您可以通过阅读代码了解什么。

当程序实际运行时,该变量可能指向类型为Book 的对象。但这只有在程序运行时才知道,因此,运行时

在 C++ 中,名称查找发生在编译时。当您像这样在对象上调用函数时:

// Type of an_object is a_struct
a_struct an_object;

an_object.member_function();

编译器会查看 a_struct 中有哪些函数可用。由于编译器正在变量已声明的结构中查找该名称,因此名称实际上是在编译时解析的。


让我们回到您的案例。您有一个指向 Libitem 的指针。如果您尝试使用箭头访问其中的内容:

old_book->something

为了解析 something 是什么,编译器会在 Libitem 中寻找它,因为 old_book 的类型是指向 的指针>自由项目。即使指针指向子类的实例,编译器可以肯定唯一知道的是所指向对象的实际类型至少是 Libitem

现在,人类比编译器知道的更多。您知道指针 old_book 指向类 Book 的一个实例。您想要访问 Book 的成员。

为此,您必须明确告诉编译器您要使用来自子类的成员。为此,您的变量必须是 Book 类型,这样编译器将在适当的类中查找。为此,您可以将变量转换为另一种类型。由于您将变量转换为层次结构中较低的类,因此称为向下转换。在这种情况下,我们可以使用的类型转换是 dynamic_cast,这种类型转换会在运行时查看指针指向的实例的实际类型是什么:

if (Book* the_old_book = dynamic_cast<Book*>(old_book)) {
// We can use the_old_book here, which his type is Book!
} else {
// The cast failed, the real for of the variable is not Book,
// and the_old_book points to nullptr
}

如您所见,我们创建了一个名为the_old_book 的新指针,它由转换结果初始化。如果 old_book 指向的实例的实际类型确实不是 Book,则转换将失败并返回 nullptr。由于这发生在运行时,我们必须使用运行时分支(if)来验证我们的新变量。如果转换失败,执行的 block 将是 else block 。

关于c++ - 在父类指针映射中存储子类指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43462857/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com