我目前正在尝试编写正确的C ++代码(让它运行对于一些小型原型来说是好的,但它很丑陋)。
我最近意识到堆和堆栈实例化的区别(O m = new O()vs O m())。
现在我有一个类,其中头文件定义了一个变量,它保存了一个表定义。
ChunkLoader.hpp:
TablePartion * tablePartial _;
ChunkLoader.cpp:
ChunkLoader(){tablePartial_ = new TablePartial(true,0,1); }
现在我想在堆栈上实例化tablePartial,但我不能使用:
TablePartial tablePartial_(true, 0, 1);
我完全失明了?如何在堆栈上分配tablePartial_?
或者我完全错了,我不能在构造函数中使用,因为它会在构造函数之后超出范围并因此被释放?但是,由于我读到堆栈变量在性能方面更好,我想使用堆栈实例化(并获得delete
的红色)。
主要原因:堆栈溢出告诉我尽可能摆脱指针。 :)
答案 0 :(得分:7)
首先,您应该避免使用堆栈上的条款"或者"在堆上",他们的实施细节与所讨论的概念无关。相反,我们讨论对象的生命周期,以automatic
(或多或少与堆栈相关),dynamic
(或多或少与堆相关),static
来讨论对象的生命周期。 (或多或少与全局变量相关)和thread
(这是一个特定于线程的全局变量)。
在回答您的具体问题时,您可以使用构造函数初始值设定项来初始化变量:
ChunkLoader()
: tablePartial_(true, 0, 1)
{
}
答案 1 :(得分:1)
由于类声明是:
class MyClass
{
SomeOtherClass x;
};
x
完全包含在MyClass
中(它不是指向SomeOtherClass
的指针)。
Ergo,在堆栈上创建对象MyClass
时,x
也将在堆栈上,当在堆上创建对象MyClass
时,x
将也在堆上。
编辑:
据我所知,你想在堆栈上分配x
。为此,MyClass
的任何实例也必须在堆栈中。为此,您可以设置new
运算符private
:
class MyClass
{
SomeOtherClass x;
private:
void* operator new(size_t);
};
答案 2 :(得分:0)
如果你没有在C ++中使用“new”这个词(避免malloc和其他C / OS调用这个对话),那么你就没有在“堆”上动态分配内存。
如果不使用new,则在main()中创建的所有内容以及在其中调用的函数都会进入堆栈。当您输入新的函数调用时,您将获得一个新的堆栈帧,并且所有变量都声明为:
void foo() {
int x;
std::string y;
}
在堆栈上创建。
你甚至可以获得一个基于堆栈的对象的“指针”,这样你就可以多态地使用它,就像指向堆对象的指针一样:
//These should be "classes" with private/public hiding but I'm being lazy.
struct MyClass {
int x;
virtual void foo();
};
//These should be "classes" with private/public hiding but I'm being lazy.
struct MyClassDerived : MyClass {
void foo() { std::cerr << "foo called!" << std::endl; }
};
int main() {
MyClassDerived x;
MyClass* = &x;
x->foo();
}