これは部分的にはスタイルに関する質問ですが、部分的には正しい質問です。それは、書かれていることを正しいscratch_
とsize_
あるC++ - 既定のメンバ初期化子とメンバ初期化リストを混在させる - 悪い考えですか?
class Foo {
public:
Foo(size_t size)
: scratch_(new uint8_t[header_length_ + size]),
size_(header_length_ + size) {
}
~Foo() {
delete[] scratch_;
}
Foo(const Foo&) = delete; // Effective C++
void operator=(const Foo&) = delete; // Effective C++
protected:
struct Header {
uint32_t a, b, c, d;
};
uint8_t * const scratch_;
size_t const size_;
Header * const header_ = reinterpret_cast<Header *>(scratch_);
static constexpr size_t header_length_ = sizeof(Header);
static constexpr size_t data_offset_ = header_length_;
size_t const data_length_ = size_ - data_offset_;
};
まず、技術的な正しさ...:次のサンプル(埋め込まれたヘッダを含むデータのブロックを扱うクラスのストリップダウン)を提出最初に初期化され、次にheader_
、次にdata_length_
? (constexpr
アイテムはコンパイル時定数であり、初期化順序には含まれません)。どのように初期化子が宣言されているか、デフォルトメンバー初期化(int foo = 5
)またはメンバー初期化子リストむしろ重要なのは、メンバーが宣言された順序だけですか?私はthis answerを見つけました。初期化順序に関するISO仕様を引用していましたが、私が収集したのは、scratch_
とsize_
がメンバー初期化リストに表示されているのに対して、デフォルトのメンバー初期化子が与えられています。他のメンバーの前にscratch_
とsize_
が宣言されていることだけが重要です。おそらく、scratch_
とsize_
が最後に宣言された場合は、header_
とdata_length_
が最初に初期化されます(望ましくない/誤って)。
スタイルに関する質問...これらの2つの初期化スタイルを混在させるのは悪いスタイルですか?私のアプローチは、メンバ初期化リスト(scratch_
、size_
)の項目はコンストラクタに渡される引数に依存し、残りのクラスメンバは他のクラスメンバから派生します。明らかに、初期化子がコンストラクタ引数に依存する場合、にはがあり、メンバ初期化リストに入ります。私はすべてのイニシャライザをメンバー初期化リストにスローする必要がありますか? IMOは、コードを少し難しくするかもしれません。思考?
私はそれが正しいと信じています。個人的にはそれほど審美的ではありませんが、他は異なるかもしれません。 –
'delete [] scratch_;' –
"*従来の初期化*"デフォルトのメンバー初期化子については " –