C++结构初始化

C++ struct initialization

本文关键字:初始化 结构 C++      更新时间:2023-10-16

我在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是一个向量,这意味着它在堆栈上有少量空间来存储指向其存储的指针以及一些开销(如大小等),但它存储的所有内容都通过它管理的分配在堆上。

dataSen存储的类型std::string实际上有少量数据存储在向量中(向量也在堆上),然后为其数据创建自己的堆分配。(可以进行一个小的字符串优化,但这超出了本文的范围)。

因此,您可以将内容读取到令牌向量中,该向量将数据存储为字符串。字符串的存储在堆上(通过向量的堆分配),实际字符的存储在字符串中(通过字符串管理的堆分配来)。

然后使用c_str()从每个字符串中获取一个const char*引用,以创建一个临时MySt(它创建了两个新字符串,由constchar*初始化)。然后将这个临时数据复制到向量中,这意味着它存储在向量管理的堆上,每个字符串数据通过字符串管理的不同分配存储在堆上。

现在。。。这些可能都不是真的,因为优化器可以做很多技巧,但这正是您所要求的。

巧合的是,如果你使用emplace_back(const char*, const char*)而不是push_back(MySt(...)),你会在原地构建它,而不是临时搭建和移动。

此外,如果您为MySt添加了一个构造函数,该构造函数采用std::string&amp;值,可以将已经创建的字符串移动到MySt中,以避免强制转换为constchar*,然后再从中创建另一个字符串。

编辑您的评论:

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容器的元素也存储在堆中