C++中的指针,多态和分段错误

ale*_*ale 3 c++ segmentation-fault

我有一个有很多孩子的家长班.Parent类中的每个函数都是纯函数,即函数没有父实现,但子函数有自己的实现.无需在那里发布代码 - 标准的东西.

我不希望人们从任何地方创建父类的直接实例化.通过让虚拟功能保持纯净,我可以安全地防范这种情况.

我的问题:根据用户的输入(字符串),我想实例化其中一个孩子.我只知道运行时哪一个.我的(不正确的?)想法是以下编译好并且正常工作,直到我将代码放入函数并返回父级.

这样可行:

Parent* parent;
if(user_input == "A") {
    Child1 child1;
    parent = &child1;
}
else if(user_input == "B") {
    Child2 child2;
    parent = &child2;
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用:

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;
}
Run Code Online (Sandbox Code Playgroud)

当我说它不起作用我的意思是,它编译但是当我这样做时我得到一个分段错误:

Parent* parent = foo(user_input);
parent->some_child_function(); // segmentation error here
Run Code Online (Sandbox Code Playgroud)

我确定这是一个关于我没有完全理解指针的愚蠢/简单的问题.在阅读了书籍/文章中的所有关于它们之后,我仍然不知道我做错了什么......它可能是一个单行修复?

谢谢 :).

sha*_*oth 10

您遇到未定义的行为:

Parent* parent;
if(user_input == "A") {
    Child1 child1; // stack-allocated object
    parent = &child1;
} //child1 is destroyed at this point, the pointer is dangling now
Run Code Online (Sandbox Code Playgroud)

你必须使用new(最好用智能指针):

Parent* parent = 0;
if(user_input == "A") {
   parent = new Child1();
} else if(user_input == "B") {
   parent = new Child2();
}
Run Code Online (Sandbox Code Playgroud)

并且在开头将指针设置为null也是一个好主意,这样如果代码中有错误并且指针未被初始化,则没有带垃圾值的指针.


Cha*_*bel 5

试试这个

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;
}
Run Code Online (Sandbox Code Playgroud)

基本上在您的版本中,对象是在堆栈上创建的,当您的方法返回时,它将被清除.using new确保在堆上创建对象,因此它一直保留到删除状态.

但是你的方法的调用者需要确保它们delete是对象,否则你会有内存泄漏.

对于生产代码使用像boost这样的库更合适.