C++ 为什么多态类型会出现错误和清除问题? #包括 #包括 #包括 #包括 类基{}; 类derived1:公共基 { 公众: 无符号短n; derived1() { n=2; } }; 类derived2:公共基{}; void main() { //方式1 { std::载体a1; std::载体a2; 地图b; a1.向后推(derived1()); b[“abc”]=&a1.at(0); std::coutn
要使C++ 为什么多态类型会出现错误和清除问题? #包括 #包括 #包括 #包括 类基{}; 类derived1:公共基 { 公众: 无符号短n; derived1() { n=2; } }; 类derived2:公共基{}; void main() { //方式1 { std::载体a1; std::载体a2; 地图b; a1.向后推(derived1()); b[“abc”]=&a1.at(0); std::coutn,c++,types,stdmap,polymorphism,C++,Types,Stdmap,Polymorphism,要使Base成为多态类型,您需要至少为其提供一个虚拟函数。在这种情况下,最简单的是析构函数: #include <iostream> #include <string> #include <map> #include <vector> class base {}; class derived1 : public base { public: unsigned short n; derived1()
Base
成为多态类型,您需要至少为其提供一个虚拟函数。在这种情况下,最简单的是析构函数:
#include <iostream>
#include <string>
#include <map>
#include <vector>
class base {};
class derived1 : public base
{
public:
unsigned short n;
derived1()
{
n = 2;
}
};
class derived2 : public base {};
void main()
{
// way 1
{
std::vector<derived1> a1;
std::vector<derived2> a2;
std::map<std::string, base*> b;
a1.push_back(derived1());
b["abc"] = &a1.at(0);
std::cout<<(dynamic_cast<derived1*>(b.find("abc")->second))->n<<std::endl;
}
// way 2
{
std::map<std::string, base*> b;
b["abc"] = new derived1();
std::cout<<dynamic_cast<derived1*>(b.find("abc")->second)->n<<std::endl;
delete dynamic_cast<derived1*>(b.find("abc")->second);
}
}
关于您关于清理的问题:
从技术上讲,这两种方式都存在一些未定义的行为,因为映射引用的对象在指针从映射中移除之前被销毁。这导致映射在销毁时包含无效指针,从而导致未定义的行为。
出于实际目的,这不会导致任何已知编译器出现任何问题 否则,您将正确地清理一切。
但在第二种方式中,您可以进行简化。当
Base
有一个虚拟析构函数时,您可以这样做
class Base {
public:
virtual ~Base() { }
};
没有动态强制转换。
main
返回类型不应该是void
。一般建议:不要存储指向向量元素的指针!一旦发生重新分配,这些指针就会无效!唯一的例外是:如果您可以保证不再发生重新分配,并且您不删除元素,这样指针将point超出了当前向量大小。感谢你写得很好的答案。我很惊讶,也很高兴我能以方式2简化删除行。这样我就可以清理指针另一侧的对象,我不知道指向的对象类型的所有信息。悬空指针不会导致未定义的行为,除非它们被解除引用。映射
不会在其析构函数或任何其他方法中解除对其基*
指针的引用。@aschepper:悬空指针也会导致UB(尽管通常有良性影响)如果在发生“左值到右值转换”的上下文中使用它们。当映射
破坏其内容时,就会发生这种转换。
delete b.find("abc")->second;