C++ C+中的指针、多态性和分段错误+;
我有一个有很多孩子的家长班。父类中的每个函数都是纯函数,即没有函数的父实现,但子类有自己的实现。不需要在那里张贴代码-标准的东西 我不希望人们在任何地方创建父类的直接实例化。我通过让虚拟函数是纯函数来防止这种情况,所以这很好 我的问题是:根据用户的输入(字符串),我想实例化一个子项。我只知道在运行时是哪一个。我(不正确?)的想法是,在我将代码放入函数并返回父函数之前,编译良好,工作正常 所以这是可行的:C++ C+中的指针、多态性和分段错误+;,c++,segmentation-fault,C++,Segmentation Fault,我有一个有很多孩子的家长班。父类中的每个函数都是纯函数,即没有函数的父实现,但子类有自己的实现。不需要在那里张贴代码-标准的东西 我不希望人们在任何地方创建父类的直接实例化。我通过让虚拟函数是纯函数来防止这种情况,所以这很好 我的问题是:根据用户的输入(字符串),我想实例化一个子项。我只知道在运行时是哪一个。我(不正确?)的想法是,在我将代码放入函数并返回父函数之前,编译良好,工作正常 所以这是可行的: Parent* parent; if(user_input == "A") { Ch
Parent* parent;
if(user_input == "A") {
Child1 child1;
parent = &child1;
}
else if(user_input == "B") {
Child2 child2;
parent = &child2;
}
但这不起作用:
Parent* foo(string user_input) {
Parent* parent;
if(user_input == "A") {
Child1 child1;
parent = &child1;
}
else if(user_input == "B") {
Child2 child2;
parent = &child2;
}
return parent;
}
当我说它不工作时,我的意思是,它会编译,但当我这样做时,我会得到一个分段错误:
Parent* parent = foo(user_input);
parent->some_child_function(); // segmentation error here
我肯定这是一个愚蠢/简单的问题,关于我没有完全理解指针???好吧,在阅读了所有关于它们的书籍/文章之后,我仍然不知道我做错了什么。。。。这可能是一个单行修复
谢谢:)。您遇到了未定义的行为:
Parent* parent;
if(user_input == "A") {
Child1 child1; // stack-allocated object
parent = &child1;
} //child1 is destroyed at this point, the pointer is dangling now
您必须使用new
(最好使用智能指针):
在开始时将指针设置为null也是一个好主意,这样在代码中出现错误且指针未初始化的情况下,就不会有一个带有垃圾值的指针。在函数
中,parent
是指向本地对象的指针,一旦程序离开功能范围,它就会被销毁。尝试在堆中构造对象,如parent=newchild1使用后,不要忘记删除父级。必须在堆上分配实现类的实例。您还需要调查。试试这个
Parent* foo(string user_input) {
Parent* parent;
if(user_input == "A") {
Child1 *child1 = new Child1();
parent = child1;
}
else if(user_input == "B") {
Child2 *child2 = new Child2();
parent = child2;
}
return parent;
}
基本上,在您的版本中,对象是在堆栈上创建的,当您的方法返回时,它将被清除。使用new
可确保在堆上创建对象,因此在删除之前,对象将一直保留在堆中
但是方法的调用者需要确保他们删除对象,否则会导致内存泄漏
对于生产代码,使用boost之类的库更合适 其他一些示例的略短版本。。。完全去掉父指针,并使用new分配变量。别忘了以后用delete销毁它
Parent* foo(string user_input)
{
if(user_input == "A") {
return new Child1();
}
else if(user_input == "B") {
return new Child2();
}
return NULL;
}
您应该研究此解决方案的解决方案。使用此模式将允许创建不同父对象的任何用户只关心工厂的接口。它还可以让您更轻松地添加不同的类型。使用此模式可能看起来是一个额外的步骤,但它为您的项目添加了一个很好的抽象层,并且为以后添加内容增加了一点灵活性
class ParentFactory
{
public:
Parent* foo(const std::string &user_input)
{
if(user_input == "A")
return new Child1;
if(user_input == "B")
return new Child2;
return 0;
}
};
你知道你不需要那些()
调用新的调用,对吗?@Nikolai-根据和,是的,你确实需要那些()
调用新的调用。嗯,不。正确的默认初始化是类的责任,而不是调用方的责任。或者我认为。。。
class ParentFactory
{
public:
Parent* foo(const std::string &user_input)
{
if(user_input == "A")
return new Child1;
if(user_input == "B")
return new Child2;
return 0;
}
};