クラスオブジェクトの初期化


クラスオブジェクトの初期化
趙湘寧
質問:クラスのテーブルデータをC++でどのように初期化しますか?C言語では、次のように構造配列を初期化できます.
//
struct MYSTRUCT {
    int x,y,z;
};

MYSTRUCT table[] = {
    { 1,2,3 },
    { 4,5,6 },
    ... // etc
};
//
しかし、MYSTRUCTが構造ではなくC++クラスであれば、コンパイル中にエラーが発生します.これはC++の一つの不足だと思います.
この問題はあなたがC++をどう思っているかにかかっています.C++の利点の一つは、正しいことを強制することです.たとえば、C++はオブジェクトを作成するときにコンストラクション関数を呼び出さないのが好きではありません.これは、一部の配列でも他のデータでも、元のデータでクラスオブジェクトを初期化できない理由です.コンストラクション関数の目的は、プログラムスタックから使用可能なメモリスタックにスペースを割り当てるか、静的配列要素として使用できるかにかかわらず、各オブジェクトが正しく初期化されることを保証することです.元のデータに構造関数をバイパスさせることが忌み嫌われること.初期のデータでオブジェクトの静的配列を作成することはできません.コンストラクション関数を呼び出す必要があります.
//
class CFooble {
    int x,y,z;
public:
    CFooble(int xx, int yy, int zz)
        : x(xx),y(yy),z(zz) { ... }
    CFooble(int i) { x=y=z=i; }
};
CFooble table[] = {
    CFooble(1,2,3),
    CFooble(4,5,6),
    CFooble(0),    // can use any constructor!
};
//
次のコードはコンパイル可能な完全な例です.
//
// StaticClassArray —         C++     C   
//       :
//
//    cl fooble.cpp
//
#include <stdio.h>

//////////////////
//       ——       ...
//
class CFooble {
protected:
   int x,y,z;

public:
   //       ...
   CFooble(int i) { x=y=z=i; }
   CFooble(int xx, int yy, int zz) : x(xx),y(yy),z(zz) { }

   //       
   void print() {
      printf("CFooble at %p: (%d,%d,%d)
", this, x, y, z); } // ... int IsEmpty() { return x==0 && y==0 && z==0; } }; #ifdef NEVER // — “ ” C++ ! CFooble table[] = { { 1,2,3 }, { 4,5,6 }, { 0,0,0 } }; #endif // : CFooble table[] = { CFooble(1,2,3), CFooble(4,5,6), CFooble(0), // ! }; void main() { for (CFooble* pc=table; !pc->IsEmpty(); pc++) { pc->print(); } } //
C++では、任意のコンストラクション関数で配列要素を初期化することができ、外部の初期華ルーチンではなく、デフォルトのコンストラクション関数で追加の要素を初期化することもできます.私にとって、これは不足ではなく進歩です.