具有以下两个使用堆的代码段。我需要更改才能使用堆栈。
prof_pair_class* ptr_prof_pair = (new prof_pair_class(
aa_profile
, bb_profile
, aa_type
, bb_type
));
和
aa_plan = new nPlan(
aa_prof_analysis
, prm_segment_data.aa_field.target_gqi
, prm_segment_data.aa_field.aa_response
, prm_segment_data.aa.user_type
);
答案 0 :(得分:4)
C ++自动/静态/动态/线程存储持续时间对象中有四种对象。
我将在这里讨论的两个是自动和动态。
这些对象是通过new
创建的,它们的寿命在传递给delete
(或等效数组)时结束。
Type* val = new Type(<param>); // Object created here.
// Will live until delete is called on val
// If you forget or there is a bug that misses the delete.
// the object will be leaked.
在现代C ++中,很少见到新的/删除内容,因为内存管理通常是通过容器或智能指针完成的(这防止了手动内存管理,这是C应用程序的祸根)。
这些对象是在当前本地范围内(在声明时)创建的,并且它们的寿命在控件退出当前范围时结束。
{
Type val(<param>); // declared here
// STUFF
} // end of scope here.
// The object's lifespan ends here and
// the object is automatically destroyed.
自动对象和动态对象都可以存在于类中。对于动态对象,没有任何变化,但是使用构造函数和析构函数有助于正确管理指针的寿命(如果正确完成(请参见5的规则))。
但是对于自动变量,变量的作用域成为其所在对象的生存期。如果父对象是自动对象,则当父对象离开作用域且其生存期结束时,子成员也是如此。如果父级是动态的,则子级成员范围将在父级传递给delete
时结束。
class X
{
Y val; // The scope of the automatic member val is X
}; // If the parent object is alive then val is alive.
{
X tmp;
} // tmp goes out of scope. Then tmp is destroyed as is tmp.val
X* ptr = new X; // the object pointed at by ptr lives until it is deleted.
// So its member val will live until the parent is deleted.
要将对象从动态转换为自动,只需停止使用new
。
// declare a dynamic variable.
prof_pair_class* ptr_prof_pair = new prof_pair_class(
aa_profile
, bb_profile
, aa_type
, bb_type
);
{
// declare an automatic variable.
prof_pair_class prof_pair(
aa_profile
, bb_profile
, aa_type
, bb_type
);
}
如果您调用的原始函数看起来像这样:
AAAAA_Facade::process_profile_dta(prof_pair_class,
&fg_prof_analysis,
&gf_prof_analysis
);
然后,您需要将呼叫更改为如下所示。
AAAAA_Facade::process_profile_dta(&prof_pair, // Add the & here.
&fg_prof_analysis,
&gf_prof_analysis
);
原因是该函数需要指向prof_pair_class
的指针。因此,预期的类型为prof_pair_class*
。自动变量的类型为prof_pair_class
,因此我们需要使用地址运算符&
将对象转换为指针。
注意:这样做有危险。如果函数期望动态分配的对象,并且您传递了自动对象的地址,则当函数在指针上调用delete时,事情可能会严重出错。因此,您应该确保该函数不希望您传递自有的ptr。
如果您对process_profile_dta()
的界面有任何控制权,我将对其进行更改。不应接受指针,而应接受对对象的引用(假设它不拥有所传递对象的所有权)。
namespace AAAAA_Facade
{
// Pass values by reference.
// This allows you to access the original objects.
// But does not imply any ownership transfer
void process_profile_dta(prof_pair_class& prof_pair,
fg_prof_analysis_class& fg_prof_analysis,
gf_prof_analysis_class& gf_prof_analysis
);
}
答案 1 :(得分:1)
我可以想到两种方法。最简单的是
prof_pair_class ptr_prof_pair(
aa_profile
, bb_profile
, aa_type
, bb_type
);
最困难的方法是为我们提供一个自定义分配器,该分配器调用alloca和一个智能指针。