1

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

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 的构造函数。有没有办法通过分配来实现这一点?

4

6 回答 6

3

你可以使用的最好的是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::swapor string::swap。效率可能与移动分配变体几乎相同。

string newContent(istreambuf_iterator<char>(filestream), istreambuf_iterator<char>());
std::swap(sFile, newContent); // or sFile.swap(newContent);
于 2012-04-18T20:05:49.440 回答
3

一种方法是使 filestream 成为成员,因此可以在构造函数初始化列表中引用它:

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>()));
    }
};
于 2012-04-18T20:12:05.500 回答
1

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

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

正确的方法是

sFile = std::string((istreambuf_iterator<char>(filestream)), istreambuf_iterator<char>());
于 2012-04-18T19:58:25.270 回答
1

你能行的。
但它不值得额外的复杂性。如果你想避免复制的成本(一个体面的编译器可能会这样做)。您可以将其加载到临时文件中,然后使用 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);
    }
};
于 2012-04-18T20:05:00.583 回答
0

使用初始化列表:

Filestring(const string &path):sFile(/*what you're initializing with*/)
{//more
}
于 2012-04-18T19:58:35.177 回答
0
sFile.assign(constructor args);
于 2012-04-18T19:58:55.537 回答