コンストラクタとデストラクタ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
たこ

コンストラクタとデストラクタ

#1

投稿記事 by たこ » 15年前

ごめんなさい。またまた投稿させてもらいます。
c++のクラスについてです。
コードは
#include<iostream>
#include<string.h>
#include<conio.h>
using namespace std;
class Cat{
public:
Cat(char *kind,char *size);
~Cat();
void show();
private:
int leg;
char body_size[32];
char kind_of_cat[32];
};
Cat::Cat(char *kind, char *size){
leg=4;
strcpy(kind_of_cat,kind);
strcpy(body_size,size);
cout<<kind_of_cat<<"のコンストラクタが呼ばれました"<<endl;
}

Cat::~Cat(void){
cout<<kind_of_cat<<"のデストラクタが呼ばれました"<<endl;
}
void Cat::show(void){
cout<<"猫の種類="<<kind_of_cat<<endl;
cout<<"足の本数="<<leg<<endl;
cout<<"体系="<<body_size<<endl;
return;
}
int main(void){
Cat MaineCoon("メイン・クーン","大型");
Cat American_Short("アメリカン・ショート・ヘア","小型");
MaineCoon.show();
cout<<'\n';
American_Short.show();
getch();
return 0;
}
全くコンストラクタとデストラクタ の仕組みがよくわかりません。
本当になにもかもわからない状態です。
このコンストラクタとデストラクタを使うとどのようなことができるようになるのでしょうか?
まずそこから教えてくれませんか?
解答お願いします><


画像

たかぎ

Re:コンストラクタとデストラクタ

#2

投稿記事 by たかぎ » 15年前

> まずそこから教えてくれませんか?

いや、まずは↓からでしょう。
[flash 600,100]http://dixq.net/flash/kiyaku4.swf[/flash]

miya

Re:コンストラクタとデストラクタ

#3

投稿記事 by miya » 15年前

たかぎさんの言う通りまずはそこから…と私も思います。
しかし、甘いと思われるかもしれませんが、自分の知識の確認のためにも答えさせて頂こうかと思います。

コンストラクタとデストラクタについてまずお話したいと思います。

クラスと言うのは構造体とは違い、変数だけでなく関数も一緒のグループとして取り扱えるものです。
その中でコンストラクタは作ったクラスを利用する際に必ず1番最初に呼ばれる関数の事を言います。

逆にデストラクタは「デス」と付くように利用するクラスが最後に呼び出す関数の事を言います。
使用しているクラスがスコープ(有効範囲)を抜ける際に呼び出されます。

どちらも戻り値を指定する事が出来ませんので関数の型を定義する必要が有りません。

コンストラクタとデストラクタは定義していなくても、自動的に「何もしない」コンストラクタとデストラクタが作られます。

ここで何かしらの処理をしたい場合はクラスを作るときに自分で定義してやる必要が有ります。
定義する場合はコンストラクタなら
クラス名(){処理}

デストラクタなら
~クラス名(){処理}

と記述します。

記載されているプログラムよりもシンプルな物を用意したのでそれを見てみましょう。
#include<iostream> 

//以降名前空間「std」を省略
using namespace std; 

class TestClass{
public:
    //コンストラクタを定義
    TestClass(){ 
        cout << "コンストラクタ実行" << endl;
    }

    //デストラクタを定義
    ~TestClass(){
        cout << "デストラクタを実行" << endl;
    }
};

int main(void){

    TestClass A; //ココでコンストラクタが呼ばれる。

    return 0;
}//ここでデストラクタが呼ばれる。
//実行結果
コンストラクタ実行
デストラクタを実行

このように自身は何かをしたつもりがないのに、勝手に呼ばれるのがコンストラクタとデストラクタです。

なお自身が設定してもpublicメンバ(公開用)にしておかないと、コンパイラが
「(自動的に)呼ぼうかと思ったけど公開されてないから無理」
と言うような事を返してきます。

今回のプログラムのコンストラクタを解説すると
Cat::Cat(char *kind, char *size){
    leg=4; //「leg」に4を代入
    strcpy(kind_of_cat,kind); //「kind_of_cat」にkind(指定された猫の名前(文字列))をコピー
    strcpy(body_size,size);    //「body_size」にsize(指定されたサイズ(文字列))をコピー

        //画面にコンストラクタが呼ばれた事を出力
    cout<<kind_of_cat<<"のコンストラクタが呼ばれました"<<endl;
}
となります。
デストラクタは自身が呼ばれた事を出力しているだけですね。

またメンバ関数show()は指定された情報を出力しているだけです。
今回はそれだけの処理をするクラスのようですね。

今回の場合を除いてコンストラクタとデストラクタを有効に使うプログラムですと…。
例えばnew(動的にメモリを確保)delete(newされた領域の開放)を利用したプログラム等があるでしょう。
deleteのし忘れは良くあるバグで、そのバグを生み出す可能性を回避する事が出来ます。
こちらもサンプルを書いてみました。
#include<iostream>
#include<string.h>

//以降名前空間「std」を省略
using namespace std; 

class TestClass{
//利用するときにはアクセスできないメンバ
private:
    char *str;

//利用するときにアクセスできるメンバ
public:
    //コンストラクタ(指定されたサイズ分配列を確保)
    TestClass(int size){
        cout << size << "Byteの領域を確保。" << endl;
        str = new char[size];
    }
    //文字列をコピー
    void get(char *st){
        strcpy(str, st);
    }
    //画面へ出力
    void show(void){
        cout << "現在「" << str << "」という文字が入っています。"  << endl;
    }
    //デストラクタ(開放)
    ~TestClass(){
        cout << "確保された領域を開放。" << endl;
        delete [/url] str;
    }
};

int main(void){
    TestClass moji(32);    //32個のchar型配列を確保

    moji.get("猫が好き");    //「猫が好き」という文字を格納
    moji.show();        //画面へ出力

    return 0;
}
//実行結果
32Byteの領域を確保。
現在「猫が好き」という文字が入っています。
確保された領域を開放。

長くなってしまいましたがコンストラクタとデストラクタというのは以上のような感じのものになります。

qwerty

Re:コンストラクタとデストラクタ

#4

投稿記事 by qwerty » 15年前

>>miyaさん
丁寧にご回答されているところ、揚げ足を取るようで申し訳ないのですが、気になったのでレスさせてもらいます。
悪気はありません・・・

>クラスと言うのは構造体とは違い、変数だけでなく関数も一緒のグループとして取り扱えるものです
構造体も関数を定義することはできますよ。

>「デス」と付くように利用するクラスが最後に呼び出す関数の事を言います
どちらかというと「デ」ですね。
反対の接頭辞ですので、「デ」がつくから「最後に~する」という意味があるわけではありませんよ。

たかぎ

Re:コンストラクタとデストラクタ

#5

投稿記事 by たかぎ » 15年前

ついでなので私も揚げ足をとります。同じく悪意はありません。

> クラスと言うのは構造体とは違い、変数だけでなく関数も一緒のグループとして取り扱えるものです。

C++では、構造体もクラスの一種です。
http://www.kijineko.co.jp/tech/supersti ... class.html

> その中でコンストラクタは作ったクラスを利用する際に必ず1番最初に呼ばれる関数の事を言います。

これも正確には違います。
作ったクラスのオブジェクトを構築する際に呼ばれる特殊なメンバ関数がコンストラクタです。

クラスを利用するだけなら、コンストラクタは必ずしも必要ではありません。
具体的には、静的メンバを使うこともできますし、クラス有効範囲で定義された型を使うことも可能です。typeidやsizeof演算子のオペランドにすることもできます。
ジェネリックプログラミングでは、セマンティクスが間違っていた場合にコンパイルエラーを生じさせるためのギミックに使ったり、タグとしてテンプレート実引数に指定するためだけに使うこともあります。

> 逆にデストラクタは「デス」と付くように利用するクラスが最後に呼び出す関数の事を言います。

語の成り立ちとしては(音節ではない点に注意)de-struct-orです。
これは、destructionという名詞から逆生された動詞destructに接尾辞-orがついたもので、元々の意味は廃棄物焼却炉や(軌道をはずれたロケット等の)破壊装置を意味します。
また、利用するクラスが最後に呼び出すのではなく、オブジェクトが解体される際に呼び出されるものです。
structは、構造体を意味するstructureと同根です。

> 使用しているクラスがスコープ(有効範囲)を抜ける際に呼び出されます。

それはオブジェクトが自動記憶域期間を持つ場合だけです。
正確には、生存期間を終える際に呼び出されます。

> 例えばnew(動的にメモリを確保)delete(newされた領域の開放)を利用したプログラム等があるでしょう。

newは動的にメモリを確保することが目的の演算子ではありません。
例えば、new(size_t, void*)のような位置指定形式の場合、メモリの確保は呼び出し側で行わなければなりません。
newは、オブジェクトを生成することが第一の目的です。

ちなみに、領域の[color=red>開放[/color]ではなく、[color=cyan>解放[/color]です。
http://www.kijineko.co.jp/tech/supersti ... -free.html

miya

Re:コンストラクタとデストラクタ

#6

投稿記事 by miya » 15年前

> おふた方
いえ、丁重に正してくくれて寧ろありがたく思います。
開放=>解放なのは素直に勘違いしていました。
自分が最初のころ(と言いましてもまだC++に触れるようになって駆け出しも良いところですが)
言われても分からなかった単語や言葉を避けて、なるべく感覚的に近いイメージを持ってもらおうと
屈曲した書き方をしたのも失敗でした…。(せめて「正くは違いますが」と入れるべきでした)

他人様の記事にこれ以上書くのも失礼と思いますので、失礼します。

閉鎖

“C言語何でも質問掲示板” へ戻る