Aritalab:Lecture/Programming/Cpp

From Metabolomics.JP
< Aritalab:Lecture | Programming(Difference between revisions)
Jump to: navigation, search
(メモリ管理)
m (コピーコンストラクタと演算子のオーバーロード)
Line 73: Line 73:
 
x = y = 既に定義されているlist_nodeクラス;
 
x = y = 既に定義されているlist_nodeクラス;
 
</pre>
 
</pre>
等と書かれたときに実行されます。上の例では、list_nodeクラスがユーザに無闇にコピーされることを防ぐためにprivate指定にしています。
+
と書かれたときに実行されます。上の例では、list_nodeクラスがユーザに無闇にコピーされることを防ぐためにprivate指定にしています。
  
 
===new と delete===
 
===new と delete===

Revision as of 17:05, 6 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 mainmake cleanと打つだけでコンパイルや片づけができます。

メモリ管理

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

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です。

クラス

Personal tools
Namespaces

Variants
Actions
Navigation
metabolites
Toolbox