簡體   English   中英

C ++結構初始化

[英]C++ struct initialization

我在somecode.h中具有以下結構聲明:

    struct MySt
    {
        MySt( const char * m, const char * gm ):
            firstSen(m),
            secondSen(gm)
        {
        }

        std::string firstSen;
        std::string secondSen;
    };

這是somecode.cpp中的代碼:

        std::vector<MySt> dataSen;

        char * cp = trim(buff);
        std::vector<std::string> tokens;

        getTokens( cp, tokens );

        if(tokens.size() == 2 )
        {

            dataSen.push_back( MySt(tokens[0].c_str(), tokens[1].c_str() ));
        }

此代碼有效。 我的問題是:這種MySt初始化類型是堆棧還是堆,是動態分配還是靜態分配? 日Thnx。

這里有很多事情。

dataSen是向量,這意味着它在堆棧上有少量空間來存儲指向其存儲的指針以及一些開銷的內容(例如大小等),但是它存儲的所有內容都通過它管理的分配在堆上。

std::string是dataSen存​​儲的類型,實際上有少量數據存儲在向量中(向量又在堆中),然后為其數據創建自己的堆分配。 (可以進行小的字符串優化,但這超出了此范圍)。

因此,您將內容讀入令牌向量,該向量將數據存儲為字符串。 字符串的存儲(通過向量的堆分配)在堆上(實際字符串在字符串內的存儲)(通過由字符串管理的堆分配)。

然后,您可以使用c_str()從每個字符串獲取const char*引用,以創建一個臨時MySt(它創建了兩個新字符串,並由const char *進行了初始化)。 然后將此臨時變量復制到向量中,這意味着它存儲在向量管理的堆中,每個字符串數據通過不同的字符串管理分配存儲在堆中。

現在...這些都不是真的,因為優化程序可以完成很多技巧,但這就是您要完成的工作。

巧合的是,如果您使用emplace_back(const char*, const char*)而不是push_back(MySt(...)) ,則可以在原地構造它,而不是進行臨時移動。

另外,如果為MySt添加了一個帶有std :: string &&值的構造函數,則可以將已經創建的字符串移到MySt中,以避免轉換為const char *,然后從中創建另一個字符串。

編輯您的評論:

struct MySt
{
    // existing constructor, creating strings from const char*
    MySt( const char * m, const char * gm ):
        firstSen(m),
        secondSen(gm)
    {
    }

    // constructor copying string inputs
    MySt( const std::string& m, const std::string& gm) :
        firstSen(m),
        secondSen(gm)
    {
    }

    // constructor moving existing strings (strings from calling code
    // will be in an unusable state other than to re-assign them to
    // something new... but it will take the allocated heap from the
    // existing strings as to avoid making another heap allocation)
    MySt( std::string&& m, std::string&& gm) :
        firstSen(std::move(m)),
        secondSen(std::move(gm))
    {
    }

    std::string firstSen;
    std::string secondSen;
};

然后用...

getTokens( cp, tokens );

if(tokens.size() == 2 )
{
    // to copy...
    dataSen.emplace_back( tokens[0], tokens[1] );

    // or to move...
    dataSen.emplace_back( std::move(tokens[0]), std::move(tokens[1]) );
}
  • 如果您全局聲明對象或將其聲明為靜態局部對象,則將對其進行靜態分配。
  • 如果在塊中聲明,它們將分配在堆棧上。
  • 如果使用new關鍵字,它們將分配在堆上。
  • STL容器的元素也存儲在堆中。

暫無
暫無

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

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