動的配列を利用したオブジェクトの管理
では次にオブジェクトを動的に大量に生成して、配列に格納して使用してみようと思います。動的に生成や消去されるオブジェクトを配列で管理するには、配列も動的に使用できる必要があります。
このサンプルでは、「vector (動的配列)」という新たな概念が導入されています。
たくさんの要素を一度に扱う際には、今までは配列(Array)を使用してきました。例えば、100個のMyCircleのインスタンスを扱いたいのであれば、今までのやり型ですと配列(Array)を使用して次のように定義していたでしょう。
1
MyCircle circles[100];
今回のサンプルでは、ユーザがクリックした回数だけ制限なくMyCircleを複製していきたいと考えています。ところが、配列はまず生成する際に確保する要素の数を指定しなければなりません。先程の配列の例では、100個以上はオブジェクトを格納できません。これを避けるために、例えば、最初から大量の数を確保する(たとえば10000個の領域を確保する)というのも一つの方法です。しかし、確保した10000という数字には根拠がなく、さらにメモリを無駄に消費してしまうという問題もあり、あまり賢い方法ではありません。
そこで、「vector (動的配列)」というものを使用します。vectorは通常の配列と違って、最初に要素数を宣言する必要がありません。要素数は必要な際に後から追加していくことが可能となっています。vectorを使うことで今回のケースのように要素の数があらかじめわからないような場合でも効率良くプログラムすることが可能です。
vectorの宣言は、下記のような書式になっています。
1
vector 《vector名》;
MyCircleのポインタ型を、動的配列(vector)であるcirclesに格納するには、下記のような書式になります。
1
vector circles;
動的配列であるcirclesは、通常の配列と同じように使用することが可能です。例えば、特定の要素の内容を参照したければ、下記のように通常の配列と同じ書式で値を取りだすことができます。下記の例では、circles配列の5番目の要素のプロパティradiusを参照しています。circles配列はポインタ型なので、プロパティを取りだすにはアロー演算子「->」を使用しているところに注意してください。
1
radius = circles[4]->radius;
通常の配列としての機能の他、vectorには様々な関数が用意されています。
at() 指定した位置の要素を返す
back() 最終要素を返す
front() 先頭要素を返す
clear() 全ての要素を削除する
front() 先頭要素を返す
insert() 要素をベクタに挿入する
pop_back() 最終要素を削除する
push_back() ベクタの末尾に要素を追加する
size() ベクタ中の要素数を返す
例えば、動的配列のcirclesの最後の要素に新規にCircleクラスのオブジェクトを追加するには、以下のように指定します。
openFrameworksのmain関数では主に2つの処理を行う。
ofSetupOpenGL:アプリケーションのウィンドウ生成
ofRunApp:描画を行う無限ループの開始
ofSetupOpenGLではウィンドウサイズを設定し,ウィンドウの生成を行う。
ofRunAppは引数としてofBaseAppのポインタを渡して,描画アプリケーションを起動する。基本的にはofBaseAppを継承しているtestAppクラスのインスタンスを引数として渡す。
testAppクラスにはdraw()やupdate()など,アプリケーションの根幹となるようなメソッドを含んでいる。そのため,openFrameworksのアプリケーション作成においてはtestAppクラスのコーディングがアプリケーション作成のメインとなる。
まず、皆さんの知りたいことはなんでしょうか?
このよくわからない(と思われる)文章の意味であることが多いと思います。
「error: no matching function for call to 意味」や実際に動いていないので「error: no matching function for call to 動かない」
また、google の関連キーワードを見てみましょう
「重複定義」となるもう1つのルートがあります。それは「同じヘッダーファイルを2つ以上の別のファイルがインクルードする」というものです。このやっかいなところは、それぞれのファイルにしてみたら、重複先のヘッダーファイルを呼んでいるだけに過ぎないという点にあります。