簡體   English   中英

將代碼從使用堆更改為使用堆棧

[英]Change code from using heap to using the stack

有以下兩個使用堆的代碼片段。 我需要更改以使用堆棧。

  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
         );

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.

內部對象

自動和動態對象都可以存在於類中。 對於動態對象,沒有任何變化,但構造函數和析構函數的使用有助於正確管理指針的生命周期(如果正確完成(請參閱五規則))。

但是對於自動變量,變量的范圍變成了它們所在對象的生命周期。如果父對象是一個自動對象,那么當父對象離開范圍並且其生命周期結束時,子成員成員也將結束。 如果父項是動態的,則子項成員范圍在父項傳遞給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.

在你的情況下。

要將您的對象從 Dynamic 轉換為自動,只需停止使用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
                            );
}

我能想到的有兩種方法。 最簡單的是

 prof_pair_class ptr_prof_pair(
      aa_profile
    , bb_profile
    , aa_type
    , bb_type
    );

對我們來說,困難的方法是一個自定義的分配器,它調用 alloca 和一個智能指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM