可以太深的 C++ 吗?类层次结构导致堆栈溢出?
假设我有一个具有过深继承的 C++ 程序,如下所示:
using namespace std;
class AbstractParentGeneration0 {
private:
...
protected:
...
public:
virtual returnVal funcName(void) = 0;
};
class AbstractParentGeneration1: virtual public AbstractParentGeneration0 {
private:
...
protected:
...
public:
virtual returnVal funcName(void) = 0;
};
.
.
.
class AbstractParentGeneration999999999: virtual public AbstractParentGeneration999999998 {
private:
...
protected:
...
public:
virtual returnVal funcName(void) = 0;
};
class ChildGeneration: public AbstractParentGeneration999999999 {
private:
...
protected:
...
public:
returnVal funcName(void) { ... };
};
假设该程序的性质使得深层继承 不能被压缩(假设它代表一个进化物种 谱系或深层分类层次结构)
调用顶级抽象类时是否存在堆栈溢出危险?
什么策略(除了“ulimit -s bytes”或折叠 抽象层次结构)C++ 程序员用来在其中工作吗 系统边界?
有没有办法使深层垂直继承层次结构扁平化 许多主机系统通过 RPC?
有人设计自己的调用堆栈机制吗?
是否有分布式网络/集群调用堆栈之类的东西?
Suppose I have a C++ program that has excessively deep inheritance as follows:
using namespace std;
class AbstractParentGeneration0 {
private:
...
protected:
...
public:
virtual returnVal funcName(void) = 0;
};
class AbstractParentGeneration1: virtual public AbstractParentGeneration0 {
private:
...
protected:
...
public:
virtual returnVal funcName(void) = 0;
};
.
.
.
class AbstractParentGeneration999999999: virtual public AbstractParentGeneration999999998 {
private:
...
protected:
...
public:
virtual returnVal funcName(void) = 0;
};
class ChildGeneration: public AbstractParentGeneration999999999 {
private:
...
protected:
...
public:
returnVal funcName(void) { ... };
};
Suppose the nature of the program is such that the deep inheritance
can not be compacted (suppose it represents an evolutionary species
lineage or a deep taxonomy hierarchy)
Isn't there a stack overflow danger when calling the top abstract class?
What strategies (other than "ulimit -s bytes" or collapsing the
abstract hierarchy) do C++ programmers use to work within
system boundaries?
Is there a way to flatten a deep vertical inheritance hierarchy across
many host systems via RPC?
Do some people design their own call stack mechanism?
Is there such a thing as a distributed network / cluster call stack?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这很可能会违反编译器的某些内部约束。如果出现问题,您将看不到运行时。
解决这个问题的一般方法是停止生成这样的代码。不要将此类数据烘焙到运行时中。相反,这应该是某种文件格式,加载并解析为类实例的层次结构,而不是类本身的层次结构。
In all likelihood, this will violate some internal constraint on the compiler. If there's a problem, you won't see the runtime.
The general way to solve this is to stop generating code like this. Don't bake this sort of data into the runtime. Instead, this should be some file format that is loaded and parsed into a hierarchy of class instances, not of classes themselves.
当然有。每个构造函数和析构函数都会调用父类中的对应函数,一直沿层次结构向上,生成非常深的调用堆栈。
如果它在构造中幸存下来,那么调用虚拟函数就可以了——这只是对最终覆盖的单个函数调用。
就我个人而言,我倾向于完全避免继承(抽象接口除外,以及我懒得很好地封装事物的情况)。
在这种情况下,我可能会建议对象的运行时层次结构,也许使用函数指针来为虚拟函数提供类似的行为;唯一的限制是存储它们所需的内存。它不像使用类型系统来表示类别那么优雅,但不太可能遇到实现限制。
There certainly is. Each constructor and destructor will call its counterpart in the parent class, all the way up the hierarchy, generating a very deep call stack.
If it survives construction, then calling the virtual function will be fine - that's just a single function call to the final override.
Personally, I tend to avoid inheritance altogether (except for abstract interfaces, and cases where I'm too lazy to encapsulate things nicely).
In this case, I might suggest a run-time hierarchy of objects, perhaps using function pointers to give a similar behaviour to virtual functions; the only constraint would be the memory needed to store them all. It's not as elegant as using the type system to represent your categories, but is less likely to run into implementation limits.
要回答您的具体问题,不在调用顶级抽象虚拟方法时,在运行时不会有堆栈溢出的危险。大多数 C++ 实现在对象实例中都有一个 vtable 指针条目,直接指向适当的实现函数。
如果您对它是如何工作的感到好奇,我建议您编写这样一个具有几个层次结构级别的程序,并加载一个汇编级调试器来显示到底发生了什么。
To answer your specific question, no there will be no danger of stack overflow at runtime when calling the top level abstract virtual method. Most implementations of C++ will have a vtable pointer entry in the object instance that points directly at the appropriate implementation function.
If you're curious about how this works, I recommend you write such a program with a few levels of hierarchy, and load up an assembly level debugger that shows you what is really going on.
尝试一下,亲自看看;)
Try that and see for yourself ;)
不是在这个简单的例子中。但是,如果您有多个虚拟继承,那么某些编译器将使用“调整器 thunks”来修复
this
。这些小函数最终将出现在您的调用堆栈上。Not in this simple case. However, if you have multiple virtual inheritance, then some compilers will use "adjustor thunks" to fix
this
. These small functions will end up on your call stack.