简体   繁体   English

C ++结构初始化

[英]C++ struct initialization

I have the following struct declaration in somecode.h: 我在somecode.h中具有以下结构声明:

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

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

Here is the code in somecode.cpp: 这是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() ));
        }

This code works. 此代码有效。 My question is: This type of MySt initialization, is it stack or heap, is it dynamically or statically allocated? 我的问题是:这种MySt初始化类型是堆栈还是堆,是动态分配还是静态分配? Thnx. 日Thnx。

There is a lot going on here. 这里有很多事情。

dataSen is a vector which means that it has a small amount of space on the stack to store a pointer to its storage as well as some overhead stuff (like size, etc) but everything it stores is on the heap via an allocation that it manages. dataSen是向量,这意味着它在堆栈上有少量空间来存储指向其存储的指针以及一些开销的内容(例如大小等),但是它存储的所有内容都通过它管理的分配在堆上。

std::string , the type stored by dataSen, actually has a small amount of data being stored inside your vector (which again, is on the heap) and then creates a heap allocation of it's own for it's data. std::string是dataSen存​​储的类型,实际上有少量数据存储在向量中(向量又在堆中),然后为其数据创建自己的堆分配。 (There is a small string optimization that can take place, but that's beyond the scope of this). (可以进行小的字符串优化,但这超出了此范围)。

So you read things into a tokens vector, which stores the data as strings. 因此,您将内容读入令牌向量,该向量将数据存储为字符串。 The storage for the strings is on the heap (through vector's heap allocation) as is the storage within the string for the actual characters (through a heap allocation managed by the string). 字符串的存储(通过向量的堆分配)在堆上(实际字符串在字符串内的存储)(通过由字符串管理的堆分配)。

Then you use c_str() to get a const char* reference from the each string to create a temporary MySt (which has create two new strings, initialized by the const char*'s). 然后,您可以使用c_str()从每个字符串获取const char*引用,以创建一个临时MySt(它创建了两个新字符串,并由const char *进行了初始化)。 This temporary is then copied into the vector, which means it is stored on the heap managed by the vector, with each of the strings data being stored on the heap through different allocations managed by string. 然后将此临时变量复制到向量中,这意味着它存储在向量管理的堆中,每个字符串数据通过不同的字符串管理分配存储在堆中。

Now... none of that might actually be true because the optimizer can do lots of tricks, but that's what you are requesting be done. 现在...这些都不是真的,因为优化程序可以完成很多技巧,但这就是您要完成的工作。

Coincidentally, if you use emplace_back(const char*, const char*) instead of push_back(MySt(...)) you would construct it in place instead of making a temporary and moving. 巧合的是,如果您使用emplace_back(const char*, const char*)而不是push_back(MySt(...)) ,则可以在原地构造它,而不是进行临时移动。

Additionally, if you added a constructor for MySt that took std::string&& values you could move the strings you have already created into MySt to avoid casting to a const char* and then creating another string from that. 另外,如果为MySt添加了一个带有std :: string &&值的构造函数,则可以将已经创建的字符串移到MySt中,以避免转换为const char *,然后从中创建另一个字符串。

Edit for your comment: 编辑您的评论:

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

Then use... 然后用...

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]) );
}
  • If you declare objects globally or as static local, they are allocated statically. 如果您全局声明对象或将其声明为静态局部对象,则将对其进行静态分配。
  • If you declare in a block, they are allocated on the stack. 如果在块中声明,它们将分配在堆栈上。
  • If you use new keyword, they are allocated on the heap. 如果使用new关键字,它们将分配在堆上。
  • Elements of STL containers are also stored on the heap. STL容器的元素也存储在堆中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM