template<class T>
Queue<T>::Queue(): frontPtr(NULL), backPtr(NULL), count(0)
{
}
Queue():
だけではないのはなぜQueue()
ですか?
template<class T>
Queue<T>::Queue(): frontPtr(NULL), backPtr(NULL), count(0)
{
}
Queue():
だけではないのはなぜQueue()
ですか?
他の人がコメントしたように、:
は初期化子リストの存在を示します。詳細については、お気に入りの C++ の本または多数の優れた Web サイトを参照してください。簡単な Google 検索で、よく書かれていると思われるこの記事が表示されました: http://www.cprogramming.com/tutorial/initialization-lists-c++.html。
初期化子リストの短いエグゼクティブ サマリーが必要な場合は、次のようにします。初期化子リストには、基本クラス コンストラクターへの呼び出しと、メンバー変数のコンストラクターへの呼び出しを含めることができます。
どうしてそんなものを欲しがるの?まあ、多くの理由。
コードはかなり単純化されており、少しばかげた部分 (Name
クラスなど) が含まれていることに注意してください。目的は、イニシャライザ リストがどのように機能するかを示すことであり、派手なコードを記述したり、考えられるすべての C++ 機能を活用したりすることではありません。
構築するためにいくつかのパラメーターを必要とする基本クラスがあるとします。コンストラクターに必要なパラメーターを渡す方法は他にありません。これは、{
コンストラクターの本体を開く が "実行" するまでに (このコンテキストでの "実行" の使用がやや緩いことを許してください)、基底クラスが既に構築されているためです。 :
class Name
{
const char *name;
public:
Base(const char *n)
{
name = n;
}
const char *getName() const
{
return name;
}
};
class Derived : public Name
{
int a;
public:
Derived(int x)
: Name("Derived")
{
a = y;
}
// Without the call to Name("Derived") in the constructor initializer
// list how could you possibly initialize the base class here?
};
同様に、引数を必要とするコンストラクターを持つクラス メンバーがあるとします。問題は似ています: 引数を渡すためにこれらのコンストラクターをどこで呼び出し、どのように渡すことができるでしょうか? 答えは初期化リストにあります。前の例を拡張してみましょう。
class Name
{
const char *name;
public:
Base(const char *n)
{
name = n;
}
const char *getName() const
{
return name;
}
};
class MyInt
{
int value;
public:
MyInt(int i)
{
value = i;
}
int getInt() const
{
return value;
}
}
class Derived : public Name
{
MyInt a;
public:
Derived(int x)
: Name("Derived"), a(x)
{
}
// Without the call to a(x) in the constructor initializer
// list how could you possibly initialize that member variable
// here?
};
代入の左側に手動で値を変数に設定する場合、実際にはそれを「初期化」していません。代わりに課題を実行しています。
これはやや難解な違いかもしれませんが、多くの重要な意味があります。その 1 つ (そして最も重要なものでさえありません) は、パフォーマンスです。
C では、すべての基底クラスとすべてのメンバー変数のコンストラクターが、コンストラクター本体の実行を開始する前に完了する必要があるため、これは、これらのコンストラクターの 1 つでかなりの量の作業が行われることを意味する場合があります。これらのメンバー変数の 1 つに新しい値を割り当てると、すべての作業が失われる可能性があります。
そのため、必要な値をコンストラクター初期化子リストに渡すことで、(型に関係なく) メンバー変数を初期化できます。最後の例を作り直してみましょう:
class Name
{
const char *name;
public:
Base(const char *n)
: name(n)
{
// notice that at this point the member variable "name"
// has already been initialized and can be accessed.
}
const char *getName() const
{
return name;
}
};
class MyInt
{
int value;
public:
MyInt(int i)
: value(i)
{
// Again, note here that the variable "value" already contains
// its value. We need not initialize it again.
}
int getInt() const
{
return value;
}
}
class Derived : public Name
{
MyInt a;
public:
Derived(int x)
: Name("Derived"), a(x)
{
}
};
物事の初期化を少し動かした方法を観察してください。私たちのプログラムは同じように動作しますが、動作が大きく異なります。理由を確認するために、別のクラスをミックスに追加してみましょう。
class Name
{
const char *name;
public:
Base(const char *n)
: name(n)
{
// notice that at this point the member variable "name"
// has already been initialized and can be accessed.
}
const char *getName() const
{
return name;
}
};
class MyInt
{
int value;
public:
MyInt(int i)
: value(i)
{
// Again, note here that the variable "value" already contains
// its value. We need not initialize it again.
}
int getInt() const
{
return value;
}
}
class Example : public MyInt
{
const char *type;
public:
Example()
: MyInt(0), type("default")
{
}
Example(int x)
: MyInt(x), type("custom")
{
}
const char *getType() const
{
return type;
}
}
class Derived : public Name
{
Example a;
Example b;
public:
Derived(int x)
: Name("Derived"), a(x)
{
}
void print()
{
std::cout << "This is an " << getName() << " instance" << std::endl;
std::cout << " a has a " << a.getType() << " value" << std::endl;
std::cout << " a=" << a.getInt() << std::endl;
std::cout << " b has a " << b.getType() << " value" << std::endl;
std::cout << " b=" << b.getInt() << std::endl;
}
};
int main(int argc, char **argv)
{
Derived d;
d.print(123);
return 0;
}
コロンは、initializer list
コンストラクターの を示します。
これにより、クラスのメンバー変数を値で初期化できます。
以下はほぼ同じです (ただし、より効率的ではありませんInitializer List
)。
template<class T>
Queue<T>::Queue()
{
frontPtr = NULL;
backPtr = NULL;
count = 0;
}
これ:
template<class T>
Queue<T>::Queue(): frontPtr(NULL), backPtr(NULL), count(0)
{
}
以下とほぼ同じ目的を達成します。
template<class T>
Queue<T>::Queue()
{
frontPtr = NULL;
backPtr = NULL;
count = 0;
}
次のようないくつかの重要な違いがあります。
const
初期化子リストを使用することが、メンバー変数を初期化できる唯一の方法です。