1

クラスを実装してrequestいます。そのコンストラクターはコマンドラインを引数として取り、クラスにはファイルサイズ、最終変更時刻などのファイルステータスがフィールドとして含まれています。

これらのフィールドに値を割り当てたいと考えています。これには、 の呼び出しfstat()、 内の値へのアクセスstruct stat、およびこれらの値の使用が含まれます。

C++コンストラクターでの代入は推奨されておらず、初期化リストを使用する必要があることは知っていますが、コンストラクター本体(括弧の間)で関数を呼び出して代入演算子を使用せずにこれらのフィールドに値を代入する方法がわかりません。

私は何をすべきか?

コンストラクター本体でそれらを初期化する必要がある場合、最初にすべてのフィールドを初期化する必要がありますNULL(デフォルトで行われていると思います)。


class request {
    vector<string> requests;
    off_t content_length;
    char* last_modified;

    public:

    explicit request(char line[]): requests(split_string(line)), content_length(NULL), last_modified(NULL) {
        struct stat sb;
        if(fstat(line[1], &sb) == -1) {
            cerr << "Error while getting file status of the file named " << line[1] << endl;
        }

        content_length = sb.st_size;
        last_modified = ctime(&sb.st_mtime);
    }
};

これは私のコードです。彼らは元気に見えますか?

4

3 に答える 3

2

メンバーの初期化リストを使用すると、コンストラクター内での割り当てよりもいくつかの利点があります。

  • コンストラクターを持つメンバー変数は、一度だけ構築されます。
  • これは、constメンバーを初期化できる唯一の方法です。

ただし、初期化が複雑すぎてコンストラクターで実行できない場合は、本体で初期化しても問題はありません。

デフォルトでは、メンバーはNULL に初期化されません。コンストラクターを持つメンバー変数 (つまり、非 POD 型) はデフォルトで初期化されますが、それだけです。

複雑な初期化を実行し、初期化子リスト内で実行する 1 つの方法は、ヘルパー関数を使用することです。

Example::Example()
  : file_size_(CalculateFileSize())
{
};

int Example::CalculateFileSize()
{
  // Complex initialization here.
  // Be careful - this instance isn't fully initialized yet.
}

このアプローチは一般に、コンストラクター本体で行うほど明確ではないため、イニシャライザー リストですべてを行う必要がある場合 (たとえば、constメンバー変数を使用している場合) にのみお勧めします。また、一度に1つのメンバー変数を初期化するためにのみきれいに使用できることに注意してください。

于 2013-10-22T20:56:05.653 に答える
2

課題自体には何の問題もありません。初期化リストの使用が推奨される理由は、構築するのに「コストがかかる」メンバーのためです。コンストラクター本体で代入する場合、2 回支払うためです。1 回目は既定のコンストラクターを使用してメンバーを構築し、次にそれに代入します。

したがって、単純な式で初期化するのが難しい特別なメンバーがある場合は、これで自殺しないでください。本体で初期化してください。問題を解消するために、(つまり、そのメンバーの) デフォルト コンストラクターを安価にするために実行したいことが 1 つあります。

2つの方法に関連する例外処理の意味合いもありますが、あなたの場合には関係ないと思います。

于 2013-10-22T20:50:20.620 に答える