Aritalab:Lecture/Programming/Cpp
m (→new と delete) |
m |
||
Line 39: | Line 39: | ||
</pre> | </pre> | ||
これを用意しておくと、<tt>make main</tt> や <tt>make clean</tt>と打つだけでコンパイルや片づけができます。 | これを用意しておくと、<tt>make main</tt> や <tt>make clean</tt>と打つだけでコンパイルや片づけができます。 | ||
+ | |||
+ | ==クラス定義== | ||
+ | <pre> | ||
+ | class class名 { | ||
+ | private: | ||
+ | // 外からアクセスできない変数やメンバー関数 | ||
+ | public: | ||
+ | // 外からアクセス可能な変数やメンバー関数 | ||
+ | }; | ||
+ | </pre> | ||
+ | と定義します。C言語における構造体との主な違いはアクセス制限です。 | ||
+ | クラス定義の中では、自分自身を<tt>this</tt>ポインタで参照することができます。 | ||
==メモリ管理== | ==メモリ管理== | ||
Line 94: | Line 106: | ||
Javaとの最大の違いは、メモリ管理を自分で行う点です。これは単に「遅れている」という訳ではなく、実時間プログラミングのようなGarbage collector(GC)が致命的となる場合でも用いられる「汎用性」と捉えられます。 | Javaとの最大の違いは、メモリ管理を自分で行う点です。これは単に「遅れている」という訳ではなく、実時間プログラミングのようなGarbage collector(GC)が致命的となる場合でも用いられる「汎用性」と捉えられます。 | ||
メモリ管理を放棄したい人に薦めるとしたら、C++で非常に有名なのが[http://www.hpl.hp.com/personal/Hans_Boehm/gc/ Boehm GC]です。 | メモリ管理を放棄したい人に薦めるとしたら、C++で非常に有名なのが[http://www.hpl.hp.com/personal/Hans_Boehm/gc/ Boehm GC]です。 | ||
− | |||
− |
Revision as of 12:11, 7 October 2010
Contents |
C++プログラミング
C++はC言語の完全な上位互換ですが、オブジェクト指向型という点でC言語とは全く違うプログラミング思想に基づいています。 簡単に言うと、JavaのようなプログラムをCで書く為に作られたと言ってよいのではないでしょうか。
マクロの利用
ヘッダーファイル
利用する関数の型情報は.hや.hhという拡張子を持つヘッダーファイルに記述し、それをプログラムの先頭で読み込みます。一番有名なヘッダーはstdio.hでしょう。
#include <stdio.h>
このヘッダーはソースとなるプログラム毎に用意するため、ディレクトリ内に.cや.cpp等のファイルと混在してくると面倒です。その場合、例えばinclというディレクトリを作り、その中にヘッダーを集めておくと便利です。
各ヘッダーファイルは、プログラム中で複数回読み込むとエラーになります。ファイルの先頭に
#ifndef LIST_HH #define LIST_HH #include "iterator.hh" : #endif
のように、ifndefのおまじないを入れておきましょう。
コンパイルの仕方
統合環境を使わない場合は、Makefileを作りましょう。Makeではタブが意味を持つので注意します。下の例では、ヘッダーをinclディレクトリに記述する場合です。(タブが重要なので、下の内容を単にcopy&pasteしても動きません。)
- 簡単な Make ファイル
CXX = g++ -pg -ansi -g -Wall -Iincl DIRS = src SRCS = $(wildcard *.cc) OBJS = $(wildcard *.o) all clean: rm -f main main: $(SRCS) $(OBJS) $(CXX) S(OBJS) -pg -o main
これを用意しておくと、make main や make cleanと打つだけでコンパイルや片づけができます。
クラス定義
class class名 { private: // 外からアクセスできない変数やメンバー関数 public: // 外からアクセス可能な変数やメンバー関数 };
と定義します。C言語における構造体との主な違いはアクセス制限です。 クラス定義の中では、自分自身をthisポインタで参照することができます。
メモリ管理
コンストラクタとデストラクタ
C++のクラス定義では、例えば以下のような記述をします。
class list_node; typedef list_node* lnode; class list_node { private: list_node(const list_node&); list_node& operator=(const list_node&); public: void* key; lnode list_pred; lnode list_succ; list_node(GenPtr x=0x0) : key(x), list_pred(0), list_succ(0) {} ~list_node() {} };
この中でlist_node(GenPtr x=0x0)とあるのがコンストラクタ、~list_node()がデストラクタで、それぞれクラスのインスタンス生成、消去時に呼び出されます。コンストラクタ内ではクラス変数の初期化、デストラクタ内では必要なくなったポインタのnull化などをしておくと良いでしょう。(後者は無駄に思えるかもしれませんが、バグをなくすのに役立ちます。)
コピーコンストラクタと演算子のオーバーロード
上の例でprivate指定でアクセス制限されているのが、コピーコンストラクタlist_node(const list_node&)と演算子=の定義list_node& operator=(const list_node&)になります。 コピーコンストラクタは、
list_node x = 既に定義されているlist_nodeクラス;
と=をつけて初期化する場合と、関数にクラスを(参照渡しではなく)値渡しするときに実行されます。 また、演算子=のほうは、
list_node x,y; x = y = 既に定義されているlist_nodeクラス;
と書かれたときに実行されます。上の例では、list_nodeクラスがユーザに無闇にコピーされることを防ぐためにprivate指定にしています。
new と delete
Cにおけるmalloc/freeと、new/deleteは同じではありません。 クラスのnew/deleteでは、コンストラクタとデストラクタが呼ばれることに注意しましょう。 基本データ型のnew/deleteは、基本的にmalloc/freeと同じですが、void*しか返さないmallocに比較して型キャストの必要がありません。
ですから、C++らしいプログラムを心がけるには、常にnew/deleteを使うと良いでしょう。
- 働きの全く同じ二つの例
char** cArray = new char*[10]; delete[] cArray; char** cArray2 = (char**) malloc(sizeof(char)*10); free(cArray2);
Garbage Collection
Javaとの最大の違いは、メモリ管理を自分で行う点です。これは単に「遅れている」という訳ではなく、実時間プログラミングのようなGarbage collector(GC)が致命的となる場合でも用いられる「汎用性」と捉えられます。 メモリ管理を放棄したい人に薦めるとしたら、C++で非常に有名なのがBoehm GCです。