2006年01月31日

シンボリックリファレンス

一般的なリファレンスの使い方では、式 $$var はリファレンス変数 $var のデリファレンスを表しています。それでは、$var がリファレンスではない場合はどうなるのでしょうか。$var の値が文字列の場合、たとえば "foo" であれば、$$var は $foo という変数を表します。これが「シンボリックリファレンス」です。次の例を見てください。

$foo = 10;
$var = "foo";
$$var = 100; # $foo を表すシンボリックリファレンス
print $foo; # 100 を表示

$$var を評価するとき、まず $var がハードリファレンスかどうか調べます。$var は "foo" という文字列なので、foo という名前の変数 $foo を評価しようとします。その結果、$foo に 100 が代入されます。この例では変数にアクセスしましたが、@$var とすれば配列 @foo に、%$var とすればハッシュ %foo にアクセスすることができます。

ただし、シンボリックリファレンスは大域変数しかアクセスできません。次の例を見てください。

sub bar {
my $foo = 10;
my $var = "foo";
print "$$var\n";
}

$foo = 100;
&bar; # 100 を表示する

関数 barの中で局所変数 $foo と $var を定義しています。$$var はシンボリックリファレンスで変数 $foo を表しますが、局所変数 $foo にアクセスするのではなく、大域変数の $foo にアクセスします。その結果 100 を表示します。
posted by シンビアン at 08:21| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

リファレンスの「ツボ」 〜 ポインタとはチト違う 〜

リファレンス(参照と呼ばれることもあります)は C++ で新たに追加された機能の1つです。これは、他のインスタンスを(文字通り)参照するという意味では、C の時代から備わっていたポインタと非常に良く似た機能といえるでしょう。その気になればリファレンスの代わりにポインタを使っても、さほど問題になることはありません。それでは、ポインタとリファレンスの違いは何なのでしょうか。また、リファレンスを使う上で注意すべきことは何なのでしょうか。今回は、このリファレンスについて深く掘り下げ、リファレンスの「ツボ」を発見していきたいと思います。
posted by シンビアン at 08:09| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

リファレンスの「ツボ」

* リファレンスとはポインタに若干の制限を加えた存在である。
* const リファレンスとテンポラリオブジェクトの寿命は、いつでも必ず等しいというわけではない。
* リファレンスを用いて引数を変更するのはやめよう。
* 戻り値にリファレンスを用いる場合は慎重に。
* テンプレートとリファレンスを併用する場合には「リファレンスへのリファレンス問題」に注意しよう。
posted by シンビアン at 08:08| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

ポインタとリファレンス

リファレンスは、変数の別名として作用するものでした。
これは、ポインタの仕組みによって構成されています。

リファレンスの正体は、「自動的に間接参照される定数ポインタ」です。

簡単に言い換えると

   ・常に*演算子が適用される

   ・ポインタ演算ができない

上のような制約があるポインタということになります。


*演算子が自動的に適用されるということは、常に間接参照されていること
になります。
よって、代入されたり参照されている先は常に変数ということになるので
別名を扱っているかのように見えます。


また、リファレンスは定数ポインタです。
ということは、ポインタ演算は全くできません。
つまり、配列の先頭要素を指して、そこから任意の要素にアクセスしたり
する事もできません。

あくまでリファレンスは、変数単体を示すものだということを忘れないで
ください。
そのため、ポインタのように高度なデータ構造を作り上げることは
できません。


リファレンスの価値はむしろ、記述が簡単になるということにあります。

例えば、よくある2数を交換するという関数の場合、

【ポインタ版】
   void exchange(int* a,int* b){
    int t;
    t = *a;
    *a = *b;
    *b = t;
   }

【リファレンス版】
   void exchange(int& a,int& b){
    int t;
    t = a;
    a = b;
    b = t;
   }

の様に、遥かにシンプルな記述ができます。
posted by シンビアン at 08:06| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

2006年01月29日

シングルトンパターン - Singleton pattern

シングルトンパターン - Singleton pattern
* コンストラクタをプライベートにする。
* インスタンスを生成するためのインタフェースを用意する。
posted by シンビアン at 00:15| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

シングルトン パターンが、自己の単一インスタンスへの参照を保持する、単純なクラスから構成されている

シングルトン パターンには、以下の長所と短所があります。
長所

* インスタンス制御 - シングルトン パターンは、他のオブジェクトが独自の Singleton オブジェクトのコピーをインスタンス化するのを防ぎ、すべてのオブジェクトが確実に単一インスタンスにアクセスできるようにします。
* 柔軟性 - クラスはインスタンス化プロセスを制御するため、クラスにはインスタンス化プロセスを変更できる柔軟性が備えられています。

短所

* オーバーヘッド - オブジェクトが参照を要求するたびに、クラスのインスタンスが既に存在するかどうかが検査されますが、検査の際には量は極めて少ないものの、なんらかのオーバーヘッドを伴います。この問題を克服するには、「C# でのシングルトンの実装」で説明されている静的初期化を使用します。
* 開発時に起こりうる混乱 - 開発者はシングルトン オブジェクト (特にクラス ライブラリ内に定義されているもの) を使用する際、このオブジェクトのインスタンス化には new キーワードを使えないことに注意する必要があります。アプリケーション開発者は、ライブラリのソースコードにアクセスできない場合があるため、このクラスを直接インスタンス化できないことは開発者にとって意外なことがあります。
* オブジェクトの有効期間 - 単一オブジェクトの削除の問題は、シングルトン パターンでは対処されません。メモリ管理を提供する言語 (たとえば .NET Framework をベースとする言語) において、インスタンスの割り当てを解除できるのは Singleton クラスだけです。これは、Singleton クラスはインスタンスへのプライベート参照を保持しているからです。C++ などの言語の場合、オブジェクトインスタンスが他のクラスによって削除されることもありますが、その場合はぶら下がり参照が Singleton クラス内部に生じることになります。

posted by シンビアン at 00:11| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

シングルトンパターン

目的

 あるクラスに対してインスタンスが1つしか存在しないことを保証し、それにアクセスするためのグローバルな方法を提供する。

構成

シングルトンパターンの主な構成クラスはClient(クライアント)とSingleton(シングルトン)である。シングルトンクラスのコンストラクタをprivateにすることで、別のクラスがシングルトンクラスのインスタンスを直接生成するのを防いでいる。代わりに別のクラスがシングルトンクラスのインスタンスを得たいときは、getInstanceメソッドを呼ぶようにする。このgetInstanceメソッドは、常に同じシングルトンクラスのインスタンスを返す静的なメソッドである。このメソッドは唯一のインスタンスを格納する変数にアクセスするが、初めて利用される前に必ずインスタンスが生成され、初期化が行われるようになっている。こうすることで生成要求を制御してインスタンスが一つしか作成されないことを保証することができる。
posted by シンビアン at 00:08| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

2006年01月28日

メッセージパッシング

メッセージパッシングとはその名の通り、オブジェクトが他のオブジェクトにメッセージを送ることによって処理を起動するしくみで、現実にはメソッドを呼び出すことを指します。つまり、オブジェクト同士が話(パッシング)をするもっとも簡単な手段で、このメッセージのことをイベントと表現することもあります。
posted by シンビアン at 21:41| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

メッセージ・パッシング

オブジェクトに対して指示を与える唯一の手段
posted by シンビアン at 21:38| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

オブジェクト指向のパラダイム

オブジェクト指向のパラダイムはメッセージパッシングです。オブジェクト間をメッセージが送受信される、そういうモデルです。
posted by シンビアン at 21:35| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

『Symbian OS C++ 実践開発技法』

ジョウ・スティックベリー(Jo Stichbury)著、(株)管理工学研究所監修、吉川邦夫訳、翔泳社
2005年 6月16日 初版発行 ISBN4-7981-0904-7 C3055 \6800E
『Symbian OS C++』シリーズ第3弾です。原著のタイトルは"Symbian OS Explained - Effective C++ Programming for Smartphones" (Wiley, 2005)。著者はPsion SoftwareでEPOC32の時代からSymbianの開発に携わってきた理系の女性技術者です。これまでの2冊ほど分厚くなく、お求めやすいお値段。Symbian OSのアーキテクチャや、特有のプログラミング、デバッグ、テスト方法などについて、執筆当時はリリース前だったversion 8での変更点を含め、かなり深く(一部ではシステムの実装まで)、具体的に説明しています。プラットフォームに依存しないという意味では、『Symbian OS C++プログラミング』の次に読む本でしょう。
posted by シンビアン at 09:30| Comment(0) | TrackBack(1) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

PDA

個人用の携帯情報端末。手のひらに収まるくらいの大きさの電子機器で、パソコンのもつ機能のうちいくつかを実装したものをいう。液晶表示装置や外部との接続端子を搭載し、電池や専用バッテリーで駆動する。シャープのザウルスやApple社のNewton、カシオのカシオペア、Palm Computing社のPalm、Handspring社のVisorなどが有名。
posted by シンビアン at 09:11| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

Symbian OS C++実践開発技法

海外はもとより、国内でも2004年11月に最大キャリアのNTTドコモがFOMA 3G向け指定OSに決定したことで、富士通など多くの携帯電話メーカーでSymbian OS搭載機種の開発がいよいよ本格化している。
そのためエンジニアの育成が急務となっているが、本書はそうしたニーズに応える格好の実践的指南書である。
Symbian OSの携帯電話への実装、ならびにSymbian OS上のアプリケーション開発には、C++の習得が必須であるが、効果的なコードを書くためには、単にC++のスキルを高めるだけでなく、本書で解説されているようなこの特殊なOSの機能と設計を十分に理解している必要がある。
本書はまた、全編を通じて「何をするべきか(そして、なぜそうするべきなのか)、何をしてはいけないのか(そして、それはなぜか)」についての的確なアドバイスが満ち溢れている。
Symbian OSの初心者からエキスパートまで常備したい定番本。


書籍分類 > プログラミング
posted by シンビアン at 09:05| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

2006年01月27日

スタティック DLL の生成

スタティック DLL を生成するためには、プロジェクトファイル ( .mmp ファイル) の TARGETTYPE を dll に設定する必要があります (例 : TARGETTYPE dll ) 。

Series 60 の DLL は、 DLL へのエントリポイントとして E32Dll() メソッドを必ず持つ必要があります。

GLDEF_C TInt E32Dll(TDllReason)
{
return 0;
}

DLL の外部からアクセスする必要のあるメソッドはすべて、ソースファイル (.cpp) でエクスポート (EXPORT_C) し、ヘッダファイル (.h) でインポート (IMPORT_C) する必要があります。

インライン関数

なぜ C でマクロを使うか?マクロは関数に比べてちょっとだけ動作が速くなります。簡単な処理を行ったり、関数ではできない特殊なことをさせるためにマクロを使用しているのではないでしょうか。インライン関数とは、C のマクロに似たものです。

インライン関数は、関数の前に inline をつけることで定義できます。使い方も定義の仕方も普通の関数となんら変わることはありません。ただ単に関数に inline とつけるだけです。

インライン関数として定義された関数は、その関数が呼び出されたところで展開されます。これはプリプロセッサマクロと同じです。呼出しごとに展開されるので実行コードは少し大きくなりますが、マクロと同様に関数呼び出しのオーバーヘッドが回避できます。

inline int min(int x1, int x2){
return (x1 < x2)? x1: x2;
}

インライン関数の利点

ほとんどのコンパイラはデバッグ版の実行コードを作る場合、インライン関数を展開するか、関数として呼び出すかを指定できます。せっかくのインライン関数を展開しないだって?これは、プログラムをステップ実行する場合にインライン関数の部分もトレースできるようになっています。マクロでステップ実行した場合にはマクロの呼び出し部分の実際のコードまでトレースできません。マクロを使って置き換えたコードにバグがあった場合にそれを発見するまでかなり時間がかかることが良くあります。インライン関数ならスイッチ一つでその内部コードまでトレース実行できます。

マクロは引数の型チェックを行いません。C++ は C よりも型のチェックが厳しい言語です。型チェックが厳しいのは、不正な型を使用した場合のバグをなるべくプログラムにいれないようにするためです。しかし、マクロではその引数の型チェックを行わないで展開してしまいます。インライン関数の場合には、通常の関数と同様に型のチェックをしてから展開されます。こちらのほうが断然安全です。

マクロの危険性をあらわすのに、よく min(x++,y); みたいなコードが使われます。これをマクロ展開すると ((x++)<(y)? (x++):(y)) と展開されてしまい、結果的に x は2つ加算されてしまいます。これは非常にわかりづらいバグの誕生です。インライン関数ではこのようなことは起こりません。
マクロの利点

マクロはコンパイラがプログラムをコンパイルする前にプリプロセッサが行うものです。ですからさまざまなトリッキーな事ができます。たとえば、プログラムからは『変数名』を出力するには実際に文字列として変数名を書き込む以外の手段はありません。マクロを使えば変数名も簡単に文字列にできます。以下のマクロは変数名とその値をプリントする物です。
#define INVALID_PRINT(s) printf(#s " is invalid: %d\n", s);

これは展開されると以下のようになります。
INVALID_PRINT(x); → printf("x is invalid: %d\n", x);

マクロを使えば、変数の値でなく変数名そのものを文字列化することが可能です。C/C++ の機能からは直接手で文字列を書く以外は不可能です。このように C/C++ では実現できないマクロ固有の機能を使う場合にはマクロを使う価値があります。
Caution インライン関数の注意

前方参照

インライン関数は完全な前方参照です。つまり、インライン関数を定義した後ろでしかその関数を使うことができません。これはマクロを定義した後でしかそのマクロを使えないのと似ています。たいていのコンパイラではインライン関数をプロトタイプ宣言しても無駄です。いくつかのファイルで共通のインライン関数を使う場合にはヘッダファイルで定義してください。
for, while, switch

インライン関数の中では for() や while(), switch() などの構文は使えません。これらを使うインライン関数は展開されないで一つの関数としてプログラムに組み込まれます。for() や while() を使うインライン関数は普通の関数として定義するかマクロに置き換えてください。これはコンパイルしてもエラーにならず、せいぜい警告されるだけでしょう。警告されなければ、もしかしたら for や while を使うインライン関数を展開してくれているのかも知れません。ちなみに if() 構文はいくらでも組み込めます。
関数ポインタ

インライン関数はコード内に展開されるため、プログラム内でのアドレスはありません。よってインライン関数から関数ポインタを取り出すことはできません。通常は関数ポインタが取り出されるインライン関数は展開されないで一つの関数としてコンパイルされます。

インライン関数

なぜ C でマクロを使うか?マクロは関数に比べてちょっとだけ動作が速くなります。簡単な処理を行ったり、関数ではできない特殊なことをさせるためにマクロを使用しているのではないでしょうか。インライン関数とは、C のマクロに似たものです。

インライン関数は、関数の前に inline をつけることで定義できます。使い方も定義の仕方も普通の関数となんら変わることはありません。ただ単に関数に inline とつけるだけです。

インライン関数として定義された関数は、その関数が呼び出されたところで展開されます。これはプリプロセッサマクロと同じです。呼出しごとに展開されるので実行コードは少し大きくなりますが、マクロと同様に関数呼び出しのオーバーヘッドが回避できます。

inline int min(int x1, int x2){
return (x1

インラインアセンブラ 【inline assembler】

C言語などで記述されたプログラムの一部に、アセンブラコード(機械語と1対1に対応した低級言語によるプログラム)を埋め込むこと。また、そのようなコードの埋め込まれたプログラム。マイクロプロセッサの性能を極限まで引き出して実行速度を高めたい場合や、メモリ使用量を極限まで減らしたい場合、特定のマイクロプロセッサが持つ拡張命令(MMX命令など)を利用したい場合などに使う。実行効率が上がる反面、機械寄りのコードが混じることによりプログラムの見通しが悪くなり、機種依存性が高まるというデメリットもある。

2006年01月26日

型定義 typedef

C言語の特徴であるデータを区別する型をプログラマが分かりやすい名称に定義し直すことができます。そのために用意されたキーワード(予約語)が typedef です。

■型定義(Type Definition)

typedef T my_type;

識別子my_type が型T を意味することになります。

* キーワード typedef は,便宜上,記憶域クラス指定子に含まれている。[C99, 6.7.1, 3] この結果,上は「式文」ではなく「宣言」に分類される。

次の場合,BOOLEAN は int を意味します。

typedef int BOOLEAN;
BOOLEAN true = 1;
BOOLEAN false = 0;

true や false は int型です。次の WEEK は要素数 7 の intの配列を意味します。

typedef int WEEK[7];
WEEK Jan1st = {4, 5, 6, 7, 8, 9, 10};

オブジェクト Jan1st は要素数 7 の int型配列です。

typedef struct list {
int n;
char str[20];
struct list *next;
} LIST;

LIST *head;

LIST は struct list型を意味し,したがって,ポインタ head は struct list型へのポインタです。
posted by シンビアン at 08:00| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

staticの使い方6〜C++における定数宣言〜

C言語では定数値をプログラムに埋め込む場合は #define をつかって定義しました。


/* C言語における定数宣言の例 */
#define MAX_VALUE 1000
#define MIN_VALUE 1

C++になり、型のチェックが厳しくなったため #define で定義した定数のように「型不定」のものはできれば使わないようにしよう、となりました。C++の参考書等を読むと定数値を扱う場合は const で変数を定義して使うように、と書いてあると思います。


// C++における定数宣言の例(駄目な例)
const int MAX_VALUE = 1000;
const int MIN_VALUE = 1;

ところがこれには欠点があります。上のような定義の仕方では、ヘッダファイル内に定数値を定義できないのです。これは、constで宣言した定数値は値の変更できないグローバル変数と同じ扱いである為、名称の衝突が起こるからだ。
そこで、C++で定数値を使いたい場合は次のように宣言の先頭にstaticをつけるとよい。


// C++における定数宣言の例
static const int MAX_VALUE = 1000;
static const int MIN_VALUE = 1;

一口メモ
const を使って定数値を宣言すると定数値を使うときに変数アクセスになるため実行速度が落ちると心配する方がいますが、その心配は無用です。よほど頭の悪いコンパイラで無い限り、コンパイル時に最適化が行われ #define で定義したマクロと同じ処理速度が得られます。
posted by シンビアン at 07:46| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

staticの使い方5〜静的メンバ変数(属性)〜

C++でプログラミングをしている時はたいていグローバル変数は使いません。グローバル変数はどこからでもアクセスできる為オブジェクト指向の「情報隠蔽」から道がそれてしまうからです。

それでも、いろいろなプログラムを実装していく上でクラス間の共通データの保持などでグローバル変数が欲しい状態があります。まぁ、あまりにもまれなので私にはそういった経験はありませんが、VCL等のGUI系のライブラリではグローバル変数を使って機能を実装している例をよくみかけます。
 
グローバル変数を使う必要がある例はまれですが、そのまれな例の中でさらにまれに「同一クラス間のみで共通する変数を持ちたい」場合があります。そういう時は、クラスの属性(メンバ変数)をstatic宣言し、静的メンバ変数にします。

静的メンバ変数を定義する方法は少し特殊でし。次の例のようにクラス宣言部の中で宣言し、クラス宣言部の外部で定義する必要があります。

// testclass.h ヘッダファイル
class testclass
{
:
static int FHandle; //静的メンバ変数の宣言
public:
:
:

};


// testclass.cpp 実装部
#include "testclass.h"

int testclass::FHandle; //静的メンバ変数の定義
posted by シンビアン at 07:45| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。