C++でのコンストラクタは、ちょっと特別な関数。例えばクラス内の変数を初期化するときに、
class A{
int n;
public:
A(void){
n = 123;
/* コンストラクタの処理 */
}
};
と書く代わりに、
class A{
int n;
public:
A(void) : n(123) { /* コンストラクタの処理 */ }
};
と書くことが出来る。intのコンストラクタをA(void)が継承している、見れる。
プロトタイプを使って書くときは、この:以降の部分は実体(.cppのほう)に書く。すなわち、
/* in A.h */
class A{
int n;
public:
A(void);
};
/* in A.cc */
A:A(void) : n(123) {
/* コンストラクタの処理 */
}
となる。
intくらいであれば普通に代入した方がむしろ見やすいが、もっと大規模なクラス(stringとか)の場合は、コンストラクタを使って書いた方が実行速度も速いし、見やすい。
C++では継承(extension)が使える。例えば、Aを継承したクラスBを作ることができる。
このとき、Bを作ったときにはまずAの引数無しのコンストラクタ(デフォルトコンストラクタ)が呼ばれ、そのあとBの然るべきコンストラクタが呼ばれる。
#include
class A{
protected;
public:
A(void){
std::cout << "A!" << std::endl;
}
A(int n){
std::cout << "A : " << n << std::endl;
}
};
class B : A{
public:
B(void) {
cout << "B!" << endl;
}
};
int main(void){
B* b = new B();
}
実行結果
A!
B!
でもこれはちょっと省略した書き方で、明示的にコンストラクタを指定するのが本流。
class B : A{
public:
B(void) : A() {
cout << "B!" << endl;
}
};
他のコンストラクタを呼ぶことも出来る。
class B : A{
public:
B(void) : A(1) {
cout << "B!" << endl;
}
};
実行結果
A : 1
B!
下のようなコード書いてみた。
#include<iostream>
class Hoge{//Hogeクラスの宣言
public:
int foo;
Hoge(int foo_){foo = foo_;} // コンストラクタ
int print(void){std::cout << foo << '\n';} // print関数
};
class SuperHoge: public Hoge{// hogeを継承したSuperHogeクラスの宣言
public:
SuperHoge(int foo_){foo = foo_ * foo_;}// コンストラクタ
};
int main(){
SuperHoge sh(3);
sh.print();
}
コンパイルすると、下のようなエラー。
test.cc: In method `SuperHoge::SuperHoge(int)':
test.cc:21: no matching function for call to `Hoge::Hoge ()'
test.cc:7: candidates are: Hoge::Hoge(int)
test.cc:15: Hoge::Hoge(const Hoge &)
SuperHogeを作る時は、まずHogeのコンストラクタが呼ばれ、さらにSuperHogeが呼ばれるのだが、
この書き方だと、呼ばれるHogeのコンストラクタには、引数は与えられないらしい。
なので、Hogeクラスの方にHoge(void){}というコンストラクタを定義する必要がある。
class Hoge{//Hogeクラスの宣言
public:
int foo;
Hoge(void){}
Hoge(int foo_){foo = foo_;} // コンストラクタ
int print(void){std::cout << foo << '\n';} // print関数
};
(追記) あるいは、下のように書くと、ちゃんとどのコンストラクタを継承するか指定できる。
class SuperHoge: public Hoge{// hogeを継承したSuperHogeクラスの宣言
public:
SuperHoge(int foo_) : Hoge(foo_) {foo = foo_ * foo_;}// コンストラクタ
};
[an error occurred while processing this directive]