C++字符串成员构造

C++ string member construction

本文关键字:成员 字符串 C++      更新时间:2023-10-16

如何使用字符串成员的构造函数?这是一个例子(我意识到这是错误的)

class Filestring {
public:
    string      sFile;
    Filestring(const string &path)
    {
        ifstream filestream(path.c_str());
        // How can I use the constructor for the member sFile??
        // I know this is wrong, but this illustrates what I want to do.
        string sFile((istreambuf_iterator<char>(filestream)), istreambuf_iterator<char>());
    }
};

所以基本上我希望能够在不做字符串复制的情况下使用成员 sFile 的构造函数。有没有办法通过作业来实现这一点?

你能用的最好的是string::assign

sFile.assign(istreambuf_iterator<char>(filestream), istreambuf_iterator<char>());

但是在 C++11 中,字符串有一个移动赋值运算符,因此执行以下操作几乎同样有效(没有字符数据的副本,字符数据被移动):

sFile = string(istreambuf_iterator<char>(filestream), istreambuf_iterator<char>());

当 C++11 移动分配不可用时,另一个技巧是使用 std::swapstring::swap .效率可能与移动分配变体几乎相同。

string newContent(istreambuf_iterator<char>(filestream), istreambuf_iterator<char>());
std::swap(sFile, newContent); // or sFile.swap(newContent);

一种方法是使文件流成为成员,以便可以在构造函数初始化列表中引用它:

class Filestring {
private:
    ifstream filestream;
public:
    string      sFile;
    Filestring(const string &path) : filestream(path.c_str()), sFile((istreambuf_iterator<char>(filestream)), istreambuf_iterator<char>())
    {}
};

为了正常工作,Filestream 必须出现在 sFile 之前的类定义中,否则它将无法及时初始化以在 sFile 构造函数中使用它。 当然,您也增加了 Filestring 类的开销。

一种更安全的技术也可以避免字符串复制的开销,那就是使用 string::swap():

class Filestring {
public:
    string      sFile;
    Filestring(const std::string &path)
    {
        std::ifstream filestream(path.c_str());
        sFile.swap(string((istreambuf_iterator<char>(filestream)), istreambuf_iterator<char>()));
    }
};

不是真的,如果你不初始化初始值设定项列表中的成员,你一定会做一个副本,这在你的情况下似乎是不可能的。

请注意,代码不会初始化成员,而是创建新的局部变量。

正确的方法是

sFile = std::string((istreambuf_iterator<char>(filestream)), istreambuf_iterator<char>());

你可以做到。
但它不值得额外的复杂性。如果你想避免复制的成本(一个体面的编译器可能会这样做)。你可以把它加载到一个临时的,然后使用std::swap()。

我会做的:

class Filestring {
public:
    string      sFile;
    Filestring(const string &path)
    {
        ifstream filestream(path.c_str());
        string data((istreambuf_iterator<char>(filestream)), istreambuf_iterator<char>());
        // Just swap the internal data structures:
        std::swap(sFile, data);
    }
};

使用初始化列表:

Filestring(const string &path):sFile(/*what you're initializing with*/)
{//more
}
sFile.assign(constructor args);