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

1 つの方法は、コンストラクターの初期化リストで参照できるように、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 に答える
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 に答える
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 に答える