プログラミング言語/C++
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
#contents
*C++とは [#sd955d2d]
-C++はC言語にクラス・テンプレート・例外処理などを加えたもの...
-標準テンプレートライブラリが存在しなかった頃から初学者に...
そういうわけで、Cをある程度理解してから勉強してからでな...
という考え方が今でも一般的なようです((参考:[[CからC++を...
-Cは理解したぜ! って人でも、「自分の書いたプログラムの...
//*もしCを習得している方ならすぐに習得できると思います。
-プログラミングの学び方、教え方も学習者の目的や背景など状...
-『[[標準C++の歴史と哲学(豊田孝の「IT談話館」):http://w...
// - 復活(確認:2009年08月08日 現在):コンテンツ、サイ...
// - (''注意'' :現在、『豊田孝の「IT談話館」』の初心者...
//InternetArchiveには連載記事の総てがあるわけではないよう...
--[[C++の学び方(By Stroustrup):http://www.ttoyota.com/p...
*インストール [#i9c592f9]
インストールは[[C言語のページ>../C]]を参照して欲しい
*C言語との(クラス・テンプレート・例外処理以外の)違い [#h9...
**関数のプロトタイプ [#kae7bbc7]
C :引数を取らない場合、voidを明示しなければならない
C++:引数を取らない場合、何も記載しないでも良い(voidを明...
C :関数のプロトタイプ宣言はしなくてもよい
C++:別ファイル内や呼出し元よりも下で関数が定義されている...
**戻り値 [#bec42213]
C :戻り値がある場合、値を返さなくてもコンパイル可能
C++:戻り値がある場合、必ず何らかの値を返さないとコンパイ...
**変数の宣言位置 [#z4acd480]
C :関数などのブロックの先頭で宣言しなければならない(注)
C++:任意の位置で宣言可能
(注)C99規格対応により、任意位置での宣言がサポートされた
**for文 [#z0b8199f]
C++:for文の初期化部分で変数が宣言可能、かつ、スコープは...
(注)VC2003の場合、"言語拡張"オプションで変更可能、かつ、...
(注2)VC6の場合、スコープはループ内に収まらず、かつオプシ...
(例)
for ( int i = 0 ; i < 5 ; i++ ){
printf("%d", i);
}
i++; // ここではiは見えない。エラー。(注に記した場合を除...
**コメント [#t994b288]
// による1行コメントが追加(注)
(注)C99規格対応により、Cにも // がサポートされた
**新しい型 [#a4553814]
新しい型として、真偽値を表す bool が追加されました。~
代入できる値は true または false のいずれかです。true は...
bool b1 = true;
bool b2 = false;
if(b1){ ... } // 実行される
if(!b2){ ... } // 偽の否定は真なのでこれも実行される
if(b2){ ... } // 実行されない
**新しい演算子 [#iadd5582]
新しい演算子として、型の情報を返す typeid が追加されまし...
**キャスト [#u6910aa1]
dynamic_cast、static_cast、reinterpret_cast、const_cast...
**参照 [#of721aa3]
参照型や、引数の参照渡しが追加(詳しくは後述)
**特定キーワードの省略 [#s28fd647]
C++では、struct, enum, classのキーワードは省略できること...
enum _sex{male, female, unknown};
struct human{
int age;
char* name;
_sex sex; // Cなら enum _sex sex; と書かねばならないが...
};
int main(){
human Taro; // Cなら struct human Taro; と書かねばなら...
return 0;
}
// 引数、返り値の型もキーワードを省略できる
human* set_default(human* hm){
hm->age = 0; hm->name = NULL; hm->sex = unknown;
return hm;
}
**パラメーター名の省略 [#s8d26354]
C++では、使わないパラメーターは名前を省略することができる。
#include <stdio.h>
int foo(int){ // 使わないパラメーターにわざわざ int dumm...
return 10;
}
int main(){
printf("%d\n", foo(0));
return 0;
}
'''注)これはC++の新機能なのですが、C/C++両用のコンパイラ...
**新しいキーワード [#z27248a1]
Cのキーワードに加えて、以下のものが新しくキーワードとして...
|CENTER:BGCOLOR(yellow): and |CENTER: bool |CENTER: catch...
|CENTER: const_cast |CENTER: delete |CENTER: dynamic_cast...
|CENTER: false |CENTER: friend |CENTER: inline |CENTER: m...
|CENTER: namespace |CENTER: new |CENTER:BGCOLOR(yellow): ...
|CENTER:BGCOLOR(yellow): or |CENTER: private |CENTER: pro...
|CENTER: reinterpret_cast |CENTER: static_cast |CENTER: t...
|CENTER: throw |CENTER: true |CENTER: try |CENTER: typeid |
|CENTER: typename |CENTER: using |CENTER: virtual |CENTER...
ただし、&color(black,yellow){論理演算系};はVC++6では予約...
*簡単なプログラム [#r8f3394c]
まずは簡単なプログラムの説明をします。
以下のコードは画面に文字の表示をするプログラムでしょう。
#include<iostream>
using namespace std;//stdという名前空間を使用する
int main()//メイン関数。すべての始まり
{
cout << "Hello,Work" <<endl;//Hello,Workと画面に表示する
return 0;//システムに0を返す。
}
説明はコメントに書いてあるとおりです
Hello,Workと書いてあるところを他の文字列にして試してみて...
他の文字列を表示することができます。
*オブジェクト指向プログラミング [#a4cfe636]
C++はクラス単位でプログラミングを行う言語です。
そもそもクラスって何?という方に簡単な説明をすると
クラスは変数や関数を一まとめにしたものです。
何のためにクラスを使うのか?というのを説明すると、
プログラムの変更をしたいとき、その変更を最小限に抑えるた...
クラスにまとめることによりプログラムそのものを書き換える...
では、上の文字表示プログラムをクラスを使って書いて見まし...
(*注意:実際に文字を表示するだけの小さなものをクラスにまと...
#include <iostream>
// PrintCharacterというクラスを宣言
class PrintCharacter {
public:
// PrintCharacterというクラスにPrintという関数がありま...
void Print( const std::string& str );
};
void PrintCharacter::Print( const std::string& str ) {
std::cout << str << std::endl; // strを表示
}
int main() {
// printCharという名前でクラスの実体を生成して使えるよ...
PrintCharacter printChar;
// Print関数を使って画面に表示
printChar.Print("Hello,Work");
return 0;
}
これで画面に表示できます。
かなり意味不明ですね。
次にこれの説明をします。
**プログラムの詳細 [#r7053a52]
先ほどの上のプログラムをコンパイルするとHello,Workが表示...
ではそのプログラムの詳細を示して行きたいと思います。
#include<iostream>
この部分はiostreamというファイルを取り込みます。こうする...
// PrintCharacterというクラスを宣言
class PrintCharacter {
public:
// PrintCharacterというクラスにPrintという関数がありま...
void Print( const std::string& str );
};
この部分はPrintCharacterというクラスを宣言します。
public:というのはこれをつけることで外からもアクセスできま...
これがないと外からアクセスできません。
int main() {
// printCharという名前でクラスの実体を生成して使えるよ...
PrintCharacter printChar;
// Print関数を使って画面に表示
printChar.Print("Hello,Work");
return 0;
}
この部分はメイン関数です。
PPrintCharacter printChar;はPrintCharacterクラスをprintCh...
printChar.Print("Hello,Work");この部分はprintCharという名...
これによって文字が表示できます。
*関数オーバーロード [#haae1e4f]
同じ名前で中身の違う関数を複数定義できます。~
関数をオーバーロードするには、関数の呼び出し時に関数が区...
//int 11 を返す関数 f()
int f(){
return 11;
}
//a+b を返す関数 f(int,int)
int f(int a,int b){
return a+b;
}
//こういうことも可能です
int f(int a,int b,int c){
return f()+a+b+c;
}
ただし、無闇に多くの関数をオーバーロードすると乱雑になり...
*演算子のオーバーロード [#l4f68f42]
演算子の機能を、関数としてプログラマが定義できます。~
これは、自前で定義したクラスの演算を分かりやすくしたい時...
演算子のオーバーロードをするには、キーワード''operator''...
//メートル
class Metre{
public:
float v;
Metre(float n){ v = n; }
};
//キロメートル
class KMetre{
public:
float v;
KMetre(float n){ v = n; }
};
//メートルとキロメートルの加算
Metre operator + (const Metre &m,const KMetre &km){
return Metre( m.v + (km.v/1000.0f) );
}
KMetre operator + (const KMetre &km,const Metre &m){
return KMetre( (m.v*1000.0f) + km.v );
}
//..........
Metre X(100);
KMetre Y(4);
//クラスは違うが、演算は可能
Metre Z=X+Y;
KMetre W=Y+X;
*参照 [#jc7a7f3a]
参照とは、エイリアスとも呼び、「変数につけられた別名」で...
-参照の宣言など~
参照を宣言するには、型名の後に & をつけます。~
例えば、int型変数aの参照bを宣言するには以下のようにします。
int a = 5;
int& b = a; // bにaを代入する感じで~
-参照の性質~
参照ははじめにも書いた通り、「ある変数の別名」であり、元...
int a = 5;
int& b = a;
b = 3;
とすると、aの値も3に変わります。( b = 3; の代わりに a = 3...
-参照の使い道~
これだけだとまったく使い道が無いように思いますが、参照を...
#include <iostream>
void inc(int& x){
x++;
}
int main(){
int a = 5;
inc(a);
std::cout << a << std::endl;
return 0;
}
このコードはどんな結果を生じるでしょうか。~
~
xはint型変数への参照であり、そこにaを渡しているので、 int...
つまり、xはaの別名になり、x++; は a++; とまったく同じ挙動...
すなわち、このプログラムを実行すると 6 が表示されます。~
このようなことはポインタを使えば実現できますが、そうする...
一階のポインタならば混乱はおきませんが、例えば FILE* への...
参照はこのようなことを防ぎ、より直感的に分かりやすいコー...
*インライン関数 [#f980021b]
C++にはインライン関数というものがあります。~
簡単に言うと、「(コンパイラが)関数のコードを、その関数...
~定義方法~~
インライン関数を定義するには、関数定義の頭に inline キー...
inline void inc(int* x){ // 定義の頭に inline を指定
(*x)++;
}
int main(){
int a = 0;
inc(&a);
return 0;
}
これをコンパイルすると、次のコードをコンパイルしたのと(ほ...
~
int main(){
int a = 0;
int* x = &a; // この部分が inc(&a) に相当
(*x)++; // この部分が inc(&a) に相当
return 0;
}
ちょうど inc の中身が inc を呼び出した位置に展開された形...
~インライン関数のメリット~
-通常の関数を使うよりも高速に動作する~
最初にも書いたように、通常の関数呼び出しを行うと、元の関...
このジャンプを行う際に、現在のレジスタの内容を保存したり...
インライン関数を使うと上に書いたように関数のコードが呼び...
~インライン関数のデメリット~
-コードが肥大化する~
通常の関数呼び出しがなぜ時間のかかる処理をしてまでジャン...
一度 inc のコードを生成してしまえば、あとは何回 inc が呼...
しかしインライン関数は関数の中身をそのまま展開するため、1...
このためコードが肥大化してしまうというデメリットがありま...
~インライン関数を使う上での注意~
-inlineを指定した関数が必ずインライン展開されるとは限らな...
コンパイラがインライン展開をするに値する(メリットの方が...
(ただし、マイクロソフトのコンパイラでは inline の代わりに...
-inline関数はプロトタイプ宣言できない~
インライン関数は宣言をヘッダに書いて定義は別のファイルに...
別ファイルにする場合は .h に直接本体を書いて、それを incl...
*テンプレート関数 [#e1ee30ef]
テンプレート関数とは、使う側の立場から見れば「引数、返り...
例えば、xの絶対値を返す関数を作りたいと考えます。~
すると、「引数、返り値ともにdouble(数値型で一番ビット幅が...
前者はどう考えてもスマートではないし、long long(C99で追加...
そこで登場するのがテンプレート関数です。~
テンプレート関数を使えば、一度コードを書けばそれをintにも...
~テンプレート関数の定義方法~~
まず具体例を見て、それから解説します。~
xの絶対値を返すテンプレート関数は次のように定義します。
template <typename T> T abs(T x){
T abs_val;
if(x >= 0) abs_val = x;
else abs_val = -1*x;
return abs_val;
}
まず一行目について
template // これはテンプレート関数ですよ、という指示
<typename T> // この宣言で以後 T という識別子(名前)は、...
T // 返り値の型。
abs(T x) // 関数の名前、引数の型、引数の名前
{ // 関数定義開始
二行目
T // 変数の型
abs_val; // T 型の変数 abs_val を宣言した
あとは見たままで、結局のところ x の絶対値を返します。~
この関数を呼び出す時には、
abs(-1.0);
abs(-500);
のようにして呼び出します。~
するとコンパイラがコンパイルするときに自動で
float abs(float x){ float abs_val; ... }
や
int abs(int x){ int abs_val; ... }
を生成してくれます。~
つまり、コンパイラから見るとテンプレート関数は「コード生...
~補足~~
引数の型が決まっていない といっても、T と書いた型はすべて...
そこで、二種類以上の違った型を引数に取りたいときは次のよ...
// 型T1のほうが型T2よりもビット幅が大きいなら true 、そ...
template <typename T1, typename T2> bool bit_large(T1 a,...
if( sizeof(a) > sizeof(b) ) return true;
else return false;
}
int main(){
char a; int b; double c;
bit_large(a, b); // T1 は char, T2 は int になり、false...
bit_large(c, b); // T1 は double, T2 は int になり、tru...
return 0;
}
また、以下のような特徴があります。
-インライン関数と同様に、本体と宣言と別々に書くことはでき...
-typename の代わりに class と書いても同じ~
ちなみに、最初に定義した abs を独自に定義した型に対して適...
例えば
struct Point{
int x; int y;
};
int main(){
Point p = {1, 2};
abs(p);
return 0;
}
のように。~
可能性は「 x >= 0 でおかしなことが起こり暴走する」か、「...
正解は後者で、暴走したりすることはありません。コンパイラ...
逆に言えば、 Point に int operator >= (int) が定義されて...
**テンプレート関数のSpecialize [#v8ad9a07]
***関数使用時のSpecialize [#yf6429ba]
テンプレート関数は、コンパイラが引数の型にあわせて自動で<...
次のようにします。
double a = abs<double>(-5);
このとき、引数が-5なので通常は int abs(int x){ ... } が生...
***関数定義時のSpecialize [#g0cdfddc]
また、関数を定義する時に、「int型に対してだけ違う処理をし...
template <typename T> T inc(T x){ // 通常のテンプレート...
return x+1; // 通常はx+1を返す
}
template <> int inc(int x){ // int型に特化したテンプレー...
return x+2; // int型が与えられたときだけx+2を返す
}
こうしてやると、引数がint型であった場合か、'''inc<int>(引...
ポイントは、
-template <> を定義のはじめに書く
-通常用の関数(template <typename T> ...)よりも後ろに書く
ことです。(template <> ... を前に書くとエラーになる)~
これは以下のようにしても実現できそうですが、微妙に動作が...
template <typename T> T inc(T x){
return x+1;
}
// int型専用の関数をオーバーロードして作っておく
int inc(int x){
return x+2;
}
それは、「使用時の特殊化」でやったように、
cout << inc<int>(5) << endl;
とした場合です。この場合、使用するコンパイラによって「通...
'''template <> int ...''' を使えばこのような曖昧さは回避...
*テンプレートクラス [#p85810ac]
**基礎 [#e49e91d3]
テンプレート関数と同様に、テンプレートクラスというものが...
これは「メンバの型が実行時に定まるクラス」です。(テンプ...
次のようにして定義します。
template <typename T>
class Point{
public:
T x, y;
Point(T x, T y){
this->x = x, this->y = y;
}
};
template <typename T> の意味はテンプレート関数と同じです...
このテンプレートクラスを使うには、次のようにします。
#include <iostream>
int main(){
Point<int> a(1, 2);
std::cout << a.x << " " << a.y << std::endl;
return 0;
}
実行結果
1 2
Point型の変数を宣言するときに、Pointの後ろに'''<型名>'''...
またテンプレート関数と同様に、二つ以上の型を取ることもで...
template <typename T1, typename T2>
class Point2{
public:
T1 x;
T2 y;
Point2(T1 x, T2 y){
this->x = x, this->y = y;
}
};
として、
#include <iostream>
int main(){
Point2<int, float> a(1, 2.5);
std::cout << a.x << " " << a.y << std::endl;
return 0;
}
のように使えば、
1 2.5
となります。
**デフォルトtypename [#recbf60f]
typenameには、一般の引数と同じように、デフォルトの値を指...
template <typename T = int> // ここに注目
class Point{
public:
T x, y;
Point(T x, T y){
this->x = x, this->y = y;
}
};
上の例のように、デフォルトで指定したい型を'''<typename T ...
このとき、
Point<> a(1, 2);
としてPoint型変数を作ると、Tにはデフォルトのintが入り、
Point<int> a(1, 2);
としたのと同じことになります。(残念ながら '''Point a(1,2)...
また、次のようなこともできます。~
template <typename T1 = int, typename T2 = T1> // T1のデ...
class Point2{
public:
T1 x;
T2 y;
Point2(T1 x, T2 y){
this->x = x, this->y = y;
}
};
このとき、次の3つは同じ意味です。
Point2<int, int> a(1, 3); // 通常の使い方
Point2<int> a(1, 3); // T1にintを指定。T2は指定し...
Point2<> a(1, 3); // 両方何も指定しない。T1は...
**補足 [#a8476bd4]
***注意 [#ff0a4fec]
テンプレートクラスは、テンプレート関数およびインライン関...
***メンバ関数の宣言と定義を分けて書く方法 [#n262bf4d]
上の注意に書いたように、メンバ関数の宣言と定義を別ファイ...
次のようにします。
template <typename T>
class Point{
public:
T x, y;
Point(T x, T y); // ここでは宣言のみ
};
temaplate <typename T> // これが実体を書くときににも...
Point<T>::Point(T x, T y){ // 通常のクラスなら Point::Po...
this->x = x, this->y = y;
}
もちろん、typenameが二つ以上あればメンバ関数定義のクラス...
template <typename T1, typename T2>
class Point2{
public:
T1 x;
T2 y;
Point2(T1 x, T2 y);
};
template <typename T1, typename T2>
Point2<T1, T2>::Point2(T1 x, T2 y){ ... }
**STL(StandardTemplateLibrary) [#q7037a7c]
C++には、テンプレートクラスの機能を利用したSTL(StandardTe...
これは何かというと、「便利な機能をまとめたクラスを、テン...
例えば、
-どんな型でも入る(テンプレートの機能)、自由に伸び縮みする...
-どんな型でも入る(テンプレートの機能)、ハッシュ表(クラス...
などがあります。~
-→[[参考サイト>#pe9f2fcd]]
//残念なことに、STLは量が多く全てを網羅して使い方を解説し...
//(ネット上では網羅しているのは恐らく『[[ProgramingPlace ...
*C++からCの関数を呼び出す方法 [#z883fba1]
C++はCの(ほぼ)上位互換であり、同じコンパイラでコンパイル...
しかし、C++からCの関数を呼び出すには注意が必要です。
例えば、 A.c というソースコードと、A.c にある関数が宣言さ...
#include <iostream>
#include "A.h"
int main(){
std::cout << a("foo_bar") << std::endl; // A.hで char*...
return 0;
}
この状態で A.c と B.cpp をプロジェクトに追加して、VisualC...
B.obj : error LNK2001: 外部シンボル ""char * __cdecl a(cha...
と表示され、ビルドできません。(VC++6.0に限らずどんな開発...
では、これを解決する方法を説明します。
**とりあえず解決法 [#of734d81]
-A.hの関数プロトタイプ宣言を、 「extern "C" {」 , 「}」 ...
-ただし、こうするとC言語の仕様から外れるので、C++のコード...
以上をふまえて、修正された A.h は次のようになります。
#ifdef __cplusplus
extern "C" {
#endif
char* a(char* s); // 元々あった宣言文たち
......
#ifdef __cplusplus
}
#endif
これでめでたくビルドに成功します。
**解説 [#ua7c866c]
なんでこんなことが必要なのか知りたい人のために解説です。~
まず、C、C++のコードはコンパイラによってアセンブリ言語に...
その際、各関数にあたる部分のコードのはじめには、ラベルと...
(例えば、たいていのCコンパイラなら a という関数のはじめに...
このラベルのつけ方が、CとC++で異なるために、extern "C" を...
C++では、同じ名前の関数でもオーバーロードが可能なため、 _...
つまり、 B.cpp の a の呼び出し部分は
call _acharp
のようになるわけです。(これは例で、実際のラベル名は符号...
しかし A.c はCモードでコンパイルされているので、関数aのラ...
では extern "C" はどのような意味があるかというと、「この...
とコンパイラに指定する働きがあります。~
このおかげで B.cpp の a の呼び出し部分が call _acharp で...
call _a
となり、めでたく関数aを見つけることができて呼び出せる、と...
注)以上を考えると、 extern "C" を使わなくても A.c をC++モ...
*ほんのり多態性の紹介 [#nff24e0f]
例えばこんなクラスを定義(Character.h)したとして
class Character
{
public:
// virtual void Say() = 0; // 一身上の都合により純粋仮...
virtual void Say() { std::cout << "セリフが無いんじゃよ...
};
class Hero : public Character
{
public:
void Say() { std::cout << "悪が栄えた試しなし!" << std...
};
class Zako : public Character
{
public:
void Say() { std::cout << "イー!" << std::endl; }
};
class Boss : public Character
{
public:
void Say() { std::cout << "やっておしまい!" << std::en...
};
こんな感じだね。よく初心者サイトに載ってる例は。
でも、これだと、どんなメリットがあるのか良くわかんないん...
#include<iostream>
#include "Character.h"
using namespace std;
int main()
{
Hero a;
Zako b;
Boss c;
a.Say();
b.Say();
c.Say();
return 0;
}
実行例
c:\>Sample
悪が栄えた試しなし!
イー!
やっておしまい!
ちなみに、こんなことはしちゃだめね。~
#include<iostream>
#include<list>
#include "Character.h"
using namespace std;
int main()
{
Hero a;
Zako b;
Boss c;
list<Character> aryCharacter;
aryCharacter.push_back(a);
aryCharacter.push_back(b);
aryCharacter.push_back(c);
for(list<Character>::iterator iter = aryCharacter.begin...
iter->Say();
}
return 0;
}
-listはSTLに含まれるコンテナで、すさまじく簡単に言ってし...
-iteratorはコンテナにアクセスするためのもので、ポインタみ...
実行例
c:\>Sample
セリフが無いんじゃよ
セリフが無いんじゃよ
セリフが無いんじゃよ
動的生成すると、ちゃんと動作するんだけど、メモリリーク対...
この例ではたった3行だけどね。
#include<iostream>
#include<list>
#include "Character.h"
using namespace std;
int main()
{
Hero a;
Zako b;
Boss c;
list<Character*> aryCharacter;
aryCharacter.push_back(new Hero);
aryCharacter.push_back(new Zako);
aryCharacter.push_back(new Boss);
for(list<Character*>::iterator iter = aryCharacter.begi...
(*iter)->Say();
}
for(list<Character*>::iterator jter = aryCharacter.begi...
delete *jter;
}
return 0;
}
実行例
c:\>Sample
悪が栄えた試しなし!
イー!
やっておしまい!
そしてメモリリーク対策としてスマートポインタ(boostライブ...
(STLにはスマートポインタとしてauto_ptrがあるけど、コンテ...
できたー! って思ってテストしたらなんか動作がおかしい…も...
って思ったのでは、せっかくの多態性の恩恵も台無しだから、...
#include<iostream>
#include<list>
#include<boost/shared_ptr.hpp>
#include "Character.h"
using namespace std;
int main()
{
typedef boost::shared_ptr<Character> pChar;
list<pChar> aryCharacter;
aryCharacter.push_back(pChar(new Hero));
aryCharacter.push_back(pChar(new Zako));
aryCharacter.push_back(pChar(new Boss));
for(list<pChar>::iterator iter = aryCharacter.begin(); ...
iter->get()->Say();
}
return 0;
}
実行例
c:\>Sample
悪が栄えた試しなし!
イー!
やっておしまい!
で、こーなってくると、動的生成部分がもーちょっとなんとか...
戻り値がCharacter*な関数があれば、いろいろ便利になる。
しかし面倒くさくなったので、興味がある人は"[[factory:http...
ググってくれたまえ!
*typeid演算子 [#qeb6122d]
C++では型の情報を表す新しい演算子、typeid が追加されまし...
sizeof と同様にして、typeid(int) や typeid(変数名) のよう...
typeid 演算子が返すのは const type_info& であり、type_inf...
class type_info {
public:
bool operator==(const type_info& rhs) const; // 二つの ...
bool operator!=(const type_info& rhs) const; // 二つの ...
int before(const type_info& rhs) const; // 引数で...
const char* name() const; // 型の名前
const char* raw_name() const; // 型の修...
};
typeid は次のように使います。~
#include <iostream>
//#include <typeinfo> // type_info クラスが宣言されてい...
using namespace std;
class A{};
int main(){
A a, aa;
int b;
cout << typeid(a).name() << endl;
cout << typeid(a).raw_name() << endl;
// a の型と aa の型が等しいか?
if( typeid(a) == typeid(aa) ){
cout << "typeid(a)==typeid(aa)" <<endl;
}
// a の型と b の型が等しいか?
if( typeid(a) == typeid(b) ){
cout << "typeid(a)==typeid(b)" <<endl;
}
return 0;
}
実行結果
class A
.?AVA@@
typeid(a)==typeid(aa)
~
-注意~
--name, raw_name の出力は環境によって変わることがあるので...
--[[Microsoftのリファレンス:http://msdn2.microsoft.com/en...
--gcc の type_info には、raw_name メンバはありません。
*参考サイト [#rb5082c0]
//
// [[オヌヌメサイト]]の項目から一部マージ
//
-[[ロベールのC++教室:http://www7b.biglobe.ne.jp/~robe/...
最初からC++を扱ってます。とはいっても、プログラミングを全...
-[[Programing Place C++編:http://www.geocities.jp/ky_webi...
-[[WisdomSoft -> C++入門:http://wisdom.sakura.ne.jp/progr...
-[[Bjarne Stroustrup: 標準C++を新しい言語として学ぶ:http:...
-[[Stroustrup: C++ Style and Technique FAQ 日本語訳:http:...
-[[豊田孝のIT談話館 標準C++の歴史と哲学>http://www.ttoyot...
// - 復活(確認:2009年08月08日 現在):コンテンツ、サイ...
// - (''注意'' :現在、『豊田孝の「IT談話館」』の初心者...
C++を中心とした知識の基礎固めに。
IT全般に関する記事の他に「VC++ 2005 Express Edition」に関...
--[[Visutal C++ 2005/2008 Express Edition(IDE無料化の背...
無料開発ツール「Visual C++ Express Edition」の活用方法
-[[コンピュータ基礎とプログラミング>http://ipl.sfc.keio.a...
MacOS X,Emacs,g++の環境でC/C++
-[[プログラミングの禁じ手Web版 C++編>http://web.archive.o...
C/C++のコードを書く上でやってはいけないことを列挙したサイ...
サイトが落ちてるのでWeb Archiveで。C MAGAZINEも休刊したし...
-[[More C++ Idioms - Wikibooks, collection of open-conten...
--[[More C++ Idioms - Wikibooks:http://ja.wikibooks.org/w...
-[[ライブラリ リンク コレクション - Cppll:http://www.cppl...
-[[link集/開発言語系/C++ - NomisoBraaan Wiki:http://www.n...
--[[link集/ライブラリ系/C++ - NomisoBraaan Wiki:http://ww...
-[[C/C++ セキュアコーディングセミナー資料 - JPCERT コーデ...
-[[CERT C++ Secure Coding Standard - CERT Secure Coding S...
-[[C++ Reference [C++ Reference]:http://www.cppreference....
--[[C++ リファレンス(日本語版) [C++ Reference]:http://www...
-[[cplusplus.com - The C++ Resources Network:http://www.c...
--[[Documentation:http://www.cplusplus.com/doc/]]
--[[C++ Reference:http://www.cplusplus.com/reference/]]
--[[C++ Sourcecode:http://www.cplusplus.com/src/]]
-[[Visual C++ の勉強部屋>http://homepage3.nifty.com/ishid...
画像処理、電気回路の計算、統計、簡単なGUIなど~
2005、2008、2010
**C++規格 [#d805cd5c]
-[[ISO/IEC JTC1/SC22/WG21 - The C++ Standards Committee:h...
-[[C++ Final Draft International Standard:http://www.kuzb...
-[[日本工業標準調査会:データベース検索-JIS検索:http://ww...
-[[JSA Web Store - JIS X 3014:2003 プログラム言語C++:h...
**STL [#pe9f2fcd]
-[[Standard Template Library プログラミング on the Web:ht...
-[[C++ Standard Template Library [C++ Reference]:http://w...
--[[C++ 標準テンプレートライブラリ [C++ Reference]:http:/...
//--[[C/C++ リファレンス > C++ 標準テンプレートライブ...
-[[角 正史のページ > STLのページ:http://www.wakhok.ac....
-[[ProgramingPlace > C++編(標準ライブラリ):http://ww...
-[[MENISYS-Labo.HP > C++Builder 邪道TIP集:http://orang...
-[[標準 C++ ライブラリ・ユーザーズガイド:http://docs.sun....
-[[Codian>http://www.kab-studio.biz/Programing/Codian/]] -
iostreamについて詳しいサイト。C++自体の解説もありますが、...
-[[S34 > STL samples:http://www.s34.co.jp/cpptechdoc/r...
-[[MSDN > Standard Template Library Samples:http://msd...
-[[MSDN > Standard Template Library Samples:http://msd...
終了行:
#contents
*C++とは [#sd955d2d]
-C++はC言語にクラス・テンプレート・例外処理などを加えたもの...
-標準テンプレートライブラリが存在しなかった頃から初学者に...
そういうわけで、Cをある程度理解してから勉強してからでな...
という考え方が今でも一般的なようです((参考:[[CからC++を...
-Cは理解したぜ! って人でも、「自分の書いたプログラムの...
//*もしCを習得している方ならすぐに習得できると思います。
-プログラミングの学び方、教え方も学習者の目的や背景など状...
-『[[標準C++の歴史と哲学(豊田孝の「IT談話館」):http://w...
// - 復活(確認:2009年08月08日 現在):コンテンツ、サイ...
// - (''注意'' :現在、『豊田孝の「IT談話館」』の初心者...
//InternetArchiveには連載記事の総てがあるわけではないよう...
--[[C++の学び方(By Stroustrup):http://www.ttoyota.com/p...
*インストール [#i9c592f9]
インストールは[[C言語のページ>../C]]を参照して欲しい
*C言語との(クラス・テンプレート・例外処理以外の)違い [#h9...
**関数のプロトタイプ [#kae7bbc7]
C :引数を取らない場合、voidを明示しなければならない
C++:引数を取らない場合、何も記載しないでも良い(voidを明...
C :関数のプロトタイプ宣言はしなくてもよい
C++:別ファイル内や呼出し元よりも下で関数が定義されている...
**戻り値 [#bec42213]
C :戻り値がある場合、値を返さなくてもコンパイル可能
C++:戻り値がある場合、必ず何らかの値を返さないとコンパイ...
**変数の宣言位置 [#z4acd480]
C :関数などのブロックの先頭で宣言しなければならない(注)
C++:任意の位置で宣言可能
(注)C99規格対応により、任意位置での宣言がサポートされた
**for文 [#z0b8199f]
C++:for文の初期化部分で変数が宣言可能、かつ、スコープは...
(注)VC2003の場合、"言語拡張"オプションで変更可能、かつ、...
(注2)VC6の場合、スコープはループ内に収まらず、かつオプシ...
(例)
for ( int i = 0 ; i < 5 ; i++ ){
printf("%d", i);
}
i++; // ここではiは見えない。エラー。(注に記した場合を除...
**コメント [#t994b288]
// による1行コメントが追加(注)
(注)C99規格対応により、Cにも // がサポートされた
**新しい型 [#a4553814]
新しい型として、真偽値を表す bool が追加されました。~
代入できる値は true または false のいずれかです。true は...
bool b1 = true;
bool b2 = false;
if(b1){ ... } // 実行される
if(!b2){ ... } // 偽の否定は真なのでこれも実行される
if(b2){ ... } // 実行されない
**新しい演算子 [#iadd5582]
新しい演算子として、型の情報を返す typeid が追加されまし...
**キャスト [#u6910aa1]
dynamic_cast、static_cast、reinterpret_cast、const_cast...
**参照 [#of721aa3]
参照型や、引数の参照渡しが追加(詳しくは後述)
**特定キーワードの省略 [#s28fd647]
C++では、struct, enum, classのキーワードは省略できること...
enum _sex{male, female, unknown};
struct human{
int age;
char* name;
_sex sex; // Cなら enum _sex sex; と書かねばならないが...
};
int main(){
human Taro; // Cなら struct human Taro; と書かねばなら...
return 0;
}
// 引数、返り値の型もキーワードを省略できる
human* set_default(human* hm){
hm->age = 0; hm->name = NULL; hm->sex = unknown;
return hm;
}
**パラメーター名の省略 [#s8d26354]
C++では、使わないパラメーターは名前を省略することができる。
#include <stdio.h>
int foo(int){ // 使わないパラメーターにわざわざ int dumm...
return 10;
}
int main(){
printf("%d\n", foo(0));
return 0;
}
'''注)これはC++の新機能なのですが、C/C++両用のコンパイラ...
**新しいキーワード [#z27248a1]
Cのキーワードに加えて、以下のものが新しくキーワードとして...
|CENTER:BGCOLOR(yellow): and |CENTER: bool |CENTER: catch...
|CENTER: const_cast |CENTER: delete |CENTER: dynamic_cast...
|CENTER: false |CENTER: friend |CENTER: inline |CENTER: m...
|CENTER: namespace |CENTER: new |CENTER:BGCOLOR(yellow): ...
|CENTER:BGCOLOR(yellow): or |CENTER: private |CENTER: pro...
|CENTER: reinterpret_cast |CENTER: static_cast |CENTER: t...
|CENTER: throw |CENTER: true |CENTER: try |CENTER: typeid |
|CENTER: typename |CENTER: using |CENTER: virtual |CENTER...
ただし、&color(black,yellow){論理演算系};はVC++6では予約...
*簡単なプログラム [#r8f3394c]
まずは簡単なプログラムの説明をします。
以下のコードは画面に文字の表示をするプログラムでしょう。
#include<iostream>
using namespace std;//stdという名前空間を使用する
int main()//メイン関数。すべての始まり
{
cout << "Hello,Work" <<endl;//Hello,Workと画面に表示する
return 0;//システムに0を返す。
}
説明はコメントに書いてあるとおりです
Hello,Workと書いてあるところを他の文字列にして試してみて...
他の文字列を表示することができます。
*オブジェクト指向プログラミング [#a4cfe636]
C++はクラス単位でプログラミングを行う言語です。
そもそもクラスって何?という方に簡単な説明をすると
クラスは変数や関数を一まとめにしたものです。
何のためにクラスを使うのか?というのを説明すると、
プログラムの変更をしたいとき、その変更を最小限に抑えるた...
クラスにまとめることによりプログラムそのものを書き換える...
では、上の文字表示プログラムをクラスを使って書いて見まし...
(*注意:実際に文字を表示するだけの小さなものをクラスにまと...
#include <iostream>
// PrintCharacterというクラスを宣言
class PrintCharacter {
public:
// PrintCharacterというクラスにPrintという関数がありま...
void Print( const std::string& str );
};
void PrintCharacter::Print( const std::string& str ) {
std::cout << str << std::endl; // strを表示
}
int main() {
// printCharという名前でクラスの実体を生成して使えるよ...
PrintCharacter printChar;
// Print関数を使って画面に表示
printChar.Print("Hello,Work");
return 0;
}
これで画面に表示できます。
かなり意味不明ですね。
次にこれの説明をします。
**プログラムの詳細 [#r7053a52]
先ほどの上のプログラムをコンパイルするとHello,Workが表示...
ではそのプログラムの詳細を示して行きたいと思います。
#include<iostream>
この部分はiostreamというファイルを取り込みます。こうする...
// PrintCharacterというクラスを宣言
class PrintCharacter {
public:
// PrintCharacterというクラスにPrintという関数がありま...
void Print( const std::string& str );
};
この部分はPrintCharacterというクラスを宣言します。
public:というのはこれをつけることで外からもアクセスできま...
これがないと外からアクセスできません。
int main() {
// printCharという名前でクラスの実体を生成して使えるよ...
PrintCharacter printChar;
// Print関数を使って画面に表示
printChar.Print("Hello,Work");
return 0;
}
この部分はメイン関数です。
PPrintCharacter printChar;はPrintCharacterクラスをprintCh...
printChar.Print("Hello,Work");この部分はprintCharという名...
これによって文字が表示できます。
*関数オーバーロード [#haae1e4f]
同じ名前で中身の違う関数を複数定義できます。~
関数をオーバーロードするには、関数の呼び出し時に関数が区...
//int 11 を返す関数 f()
int f(){
return 11;
}
//a+b を返す関数 f(int,int)
int f(int a,int b){
return a+b;
}
//こういうことも可能です
int f(int a,int b,int c){
return f()+a+b+c;
}
ただし、無闇に多くの関数をオーバーロードすると乱雑になり...
*演算子のオーバーロード [#l4f68f42]
演算子の機能を、関数としてプログラマが定義できます。~
これは、自前で定義したクラスの演算を分かりやすくしたい時...
演算子のオーバーロードをするには、キーワード''operator''...
//メートル
class Metre{
public:
float v;
Metre(float n){ v = n; }
};
//キロメートル
class KMetre{
public:
float v;
KMetre(float n){ v = n; }
};
//メートルとキロメートルの加算
Metre operator + (const Metre &m,const KMetre &km){
return Metre( m.v + (km.v/1000.0f) );
}
KMetre operator + (const KMetre &km,const Metre &m){
return KMetre( (m.v*1000.0f) + km.v );
}
//..........
Metre X(100);
KMetre Y(4);
//クラスは違うが、演算は可能
Metre Z=X+Y;
KMetre W=Y+X;
*参照 [#jc7a7f3a]
参照とは、エイリアスとも呼び、「変数につけられた別名」で...
-参照の宣言など~
参照を宣言するには、型名の後に & をつけます。~
例えば、int型変数aの参照bを宣言するには以下のようにします。
int a = 5;
int& b = a; // bにaを代入する感じで~
-参照の性質~
参照ははじめにも書いた通り、「ある変数の別名」であり、元...
int a = 5;
int& b = a;
b = 3;
とすると、aの値も3に変わります。( b = 3; の代わりに a = 3...
-参照の使い道~
これだけだとまったく使い道が無いように思いますが、参照を...
#include <iostream>
void inc(int& x){
x++;
}
int main(){
int a = 5;
inc(a);
std::cout << a << std::endl;
return 0;
}
このコードはどんな結果を生じるでしょうか。~
~
xはint型変数への参照であり、そこにaを渡しているので、 int...
つまり、xはaの別名になり、x++; は a++; とまったく同じ挙動...
すなわち、このプログラムを実行すると 6 が表示されます。~
このようなことはポインタを使えば実現できますが、そうする...
一階のポインタならば混乱はおきませんが、例えば FILE* への...
参照はこのようなことを防ぎ、より直感的に分かりやすいコー...
*インライン関数 [#f980021b]
C++にはインライン関数というものがあります。~
簡単に言うと、「(コンパイラが)関数のコードを、その関数...
~定義方法~~
インライン関数を定義するには、関数定義の頭に inline キー...
inline void inc(int* x){ // 定義の頭に inline を指定
(*x)++;
}
int main(){
int a = 0;
inc(&a);
return 0;
}
これをコンパイルすると、次のコードをコンパイルしたのと(ほ...
~
int main(){
int a = 0;
int* x = &a; // この部分が inc(&a) に相当
(*x)++; // この部分が inc(&a) に相当
return 0;
}
ちょうど inc の中身が inc を呼び出した位置に展開された形...
~インライン関数のメリット~
-通常の関数を使うよりも高速に動作する~
最初にも書いたように、通常の関数呼び出しを行うと、元の関...
このジャンプを行う際に、現在のレジスタの内容を保存したり...
インライン関数を使うと上に書いたように関数のコードが呼び...
~インライン関数のデメリット~
-コードが肥大化する~
通常の関数呼び出しがなぜ時間のかかる処理をしてまでジャン...
一度 inc のコードを生成してしまえば、あとは何回 inc が呼...
しかしインライン関数は関数の中身をそのまま展開するため、1...
このためコードが肥大化してしまうというデメリットがありま...
~インライン関数を使う上での注意~
-inlineを指定した関数が必ずインライン展開されるとは限らな...
コンパイラがインライン展開をするに値する(メリットの方が...
(ただし、マイクロソフトのコンパイラでは inline の代わりに...
-inline関数はプロトタイプ宣言できない~
インライン関数は宣言をヘッダに書いて定義は別のファイルに...
別ファイルにする場合は .h に直接本体を書いて、それを incl...
*テンプレート関数 [#e1ee30ef]
テンプレート関数とは、使う側の立場から見れば「引数、返り...
例えば、xの絶対値を返す関数を作りたいと考えます。~
すると、「引数、返り値ともにdouble(数値型で一番ビット幅が...
前者はどう考えてもスマートではないし、long long(C99で追加...
そこで登場するのがテンプレート関数です。~
テンプレート関数を使えば、一度コードを書けばそれをintにも...
~テンプレート関数の定義方法~~
まず具体例を見て、それから解説します。~
xの絶対値を返すテンプレート関数は次のように定義します。
template <typename T> T abs(T x){
T abs_val;
if(x >= 0) abs_val = x;
else abs_val = -1*x;
return abs_val;
}
まず一行目について
template // これはテンプレート関数ですよ、という指示
<typename T> // この宣言で以後 T という識別子(名前)は、...
T // 返り値の型。
abs(T x) // 関数の名前、引数の型、引数の名前
{ // 関数定義開始
二行目
T // 変数の型
abs_val; // T 型の変数 abs_val を宣言した
あとは見たままで、結局のところ x の絶対値を返します。~
この関数を呼び出す時には、
abs(-1.0);
abs(-500);
のようにして呼び出します。~
するとコンパイラがコンパイルするときに自動で
float abs(float x){ float abs_val; ... }
や
int abs(int x){ int abs_val; ... }
を生成してくれます。~
つまり、コンパイラから見るとテンプレート関数は「コード生...
~補足~~
引数の型が決まっていない といっても、T と書いた型はすべて...
そこで、二種類以上の違った型を引数に取りたいときは次のよ...
// 型T1のほうが型T2よりもビット幅が大きいなら true 、そ...
template <typename T1, typename T2> bool bit_large(T1 a,...
if( sizeof(a) > sizeof(b) ) return true;
else return false;
}
int main(){
char a; int b; double c;
bit_large(a, b); // T1 は char, T2 は int になり、false...
bit_large(c, b); // T1 は double, T2 は int になり、tru...
return 0;
}
また、以下のような特徴があります。
-インライン関数と同様に、本体と宣言と別々に書くことはでき...
-typename の代わりに class と書いても同じ~
ちなみに、最初に定義した abs を独自に定義した型に対して適...
例えば
struct Point{
int x; int y;
};
int main(){
Point p = {1, 2};
abs(p);
return 0;
}
のように。~
可能性は「 x >= 0 でおかしなことが起こり暴走する」か、「...
正解は後者で、暴走したりすることはありません。コンパイラ...
逆に言えば、 Point に int operator >= (int) が定義されて...
**テンプレート関数のSpecialize [#v8ad9a07]
***関数使用時のSpecialize [#yf6429ba]
テンプレート関数は、コンパイラが引数の型にあわせて自動で<...
次のようにします。
double a = abs<double>(-5);
このとき、引数が-5なので通常は int abs(int x){ ... } が生...
***関数定義時のSpecialize [#g0cdfddc]
また、関数を定義する時に、「int型に対してだけ違う処理をし...
template <typename T> T inc(T x){ // 通常のテンプレート...
return x+1; // 通常はx+1を返す
}
template <> int inc(int x){ // int型に特化したテンプレー...
return x+2; // int型が与えられたときだけx+2を返す
}
こうしてやると、引数がint型であった場合か、'''inc<int>(引...
ポイントは、
-template <> を定義のはじめに書く
-通常用の関数(template <typename T> ...)よりも後ろに書く
ことです。(template <> ... を前に書くとエラーになる)~
これは以下のようにしても実現できそうですが、微妙に動作が...
template <typename T> T inc(T x){
return x+1;
}
// int型専用の関数をオーバーロードして作っておく
int inc(int x){
return x+2;
}
それは、「使用時の特殊化」でやったように、
cout << inc<int>(5) << endl;
とした場合です。この場合、使用するコンパイラによって「通...
'''template <> int ...''' を使えばこのような曖昧さは回避...
*テンプレートクラス [#p85810ac]
**基礎 [#e49e91d3]
テンプレート関数と同様に、テンプレートクラスというものが...
これは「メンバの型が実行時に定まるクラス」です。(テンプ...
次のようにして定義します。
template <typename T>
class Point{
public:
T x, y;
Point(T x, T y){
this->x = x, this->y = y;
}
};
template <typename T> の意味はテンプレート関数と同じです...
このテンプレートクラスを使うには、次のようにします。
#include <iostream>
int main(){
Point<int> a(1, 2);
std::cout << a.x << " " << a.y << std::endl;
return 0;
}
実行結果
1 2
Point型の変数を宣言するときに、Pointの後ろに'''<型名>'''...
またテンプレート関数と同様に、二つ以上の型を取ることもで...
template <typename T1, typename T2>
class Point2{
public:
T1 x;
T2 y;
Point2(T1 x, T2 y){
this->x = x, this->y = y;
}
};
として、
#include <iostream>
int main(){
Point2<int, float> a(1, 2.5);
std::cout << a.x << " " << a.y << std::endl;
return 0;
}
のように使えば、
1 2.5
となります。
**デフォルトtypename [#recbf60f]
typenameには、一般の引数と同じように、デフォルトの値を指...
template <typename T = int> // ここに注目
class Point{
public:
T x, y;
Point(T x, T y){
this->x = x, this->y = y;
}
};
上の例のように、デフォルトで指定したい型を'''<typename T ...
このとき、
Point<> a(1, 2);
としてPoint型変数を作ると、Tにはデフォルトのintが入り、
Point<int> a(1, 2);
としたのと同じことになります。(残念ながら '''Point a(1,2)...
また、次のようなこともできます。~
template <typename T1 = int, typename T2 = T1> // T1のデ...
class Point2{
public:
T1 x;
T2 y;
Point2(T1 x, T2 y){
this->x = x, this->y = y;
}
};
このとき、次の3つは同じ意味です。
Point2<int, int> a(1, 3); // 通常の使い方
Point2<int> a(1, 3); // T1にintを指定。T2は指定し...
Point2<> a(1, 3); // 両方何も指定しない。T1は...
**補足 [#a8476bd4]
***注意 [#ff0a4fec]
テンプレートクラスは、テンプレート関数およびインライン関...
***メンバ関数の宣言と定義を分けて書く方法 [#n262bf4d]
上の注意に書いたように、メンバ関数の宣言と定義を別ファイ...
次のようにします。
template <typename T>
class Point{
public:
T x, y;
Point(T x, T y); // ここでは宣言のみ
};
temaplate <typename T> // これが実体を書くときににも...
Point<T>::Point(T x, T y){ // 通常のクラスなら Point::Po...
this->x = x, this->y = y;
}
もちろん、typenameが二つ以上あればメンバ関数定義のクラス...
template <typename T1, typename T2>
class Point2{
public:
T1 x;
T2 y;
Point2(T1 x, T2 y);
};
template <typename T1, typename T2>
Point2<T1, T2>::Point2(T1 x, T2 y){ ... }
**STL(StandardTemplateLibrary) [#q7037a7c]
C++には、テンプレートクラスの機能を利用したSTL(StandardTe...
これは何かというと、「便利な機能をまとめたクラスを、テン...
例えば、
-どんな型でも入る(テンプレートの機能)、自由に伸び縮みする...
-どんな型でも入る(テンプレートの機能)、ハッシュ表(クラス...
などがあります。~
-→[[参考サイト>#pe9f2fcd]]
//残念なことに、STLは量が多く全てを網羅して使い方を解説し...
//(ネット上では網羅しているのは恐らく『[[ProgramingPlace ...
*C++からCの関数を呼び出す方法 [#z883fba1]
C++はCの(ほぼ)上位互換であり、同じコンパイラでコンパイル...
しかし、C++からCの関数を呼び出すには注意が必要です。
例えば、 A.c というソースコードと、A.c にある関数が宣言さ...
#include <iostream>
#include "A.h"
int main(){
std::cout << a("foo_bar") << std::endl; // A.hで char*...
return 0;
}
この状態で A.c と B.cpp をプロジェクトに追加して、VisualC...
B.obj : error LNK2001: 外部シンボル ""char * __cdecl a(cha...
と表示され、ビルドできません。(VC++6.0に限らずどんな開発...
では、これを解決する方法を説明します。
**とりあえず解決法 [#of734d81]
-A.hの関数プロトタイプ宣言を、 「extern "C" {」 , 「}」 ...
-ただし、こうするとC言語の仕様から外れるので、C++のコード...
以上をふまえて、修正された A.h は次のようになります。
#ifdef __cplusplus
extern "C" {
#endif
char* a(char* s); // 元々あった宣言文たち
......
#ifdef __cplusplus
}
#endif
これでめでたくビルドに成功します。
**解説 [#ua7c866c]
なんでこんなことが必要なのか知りたい人のために解説です。~
まず、C、C++のコードはコンパイラによってアセンブリ言語に...
その際、各関数にあたる部分のコードのはじめには、ラベルと...
(例えば、たいていのCコンパイラなら a という関数のはじめに...
このラベルのつけ方が、CとC++で異なるために、extern "C" を...
C++では、同じ名前の関数でもオーバーロードが可能なため、 _...
つまり、 B.cpp の a の呼び出し部分は
call _acharp
のようになるわけです。(これは例で、実際のラベル名は符号...
しかし A.c はCモードでコンパイルされているので、関数aのラ...
では extern "C" はどのような意味があるかというと、「この...
とコンパイラに指定する働きがあります。~
このおかげで B.cpp の a の呼び出し部分が call _acharp で...
call _a
となり、めでたく関数aを見つけることができて呼び出せる、と...
注)以上を考えると、 extern "C" を使わなくても A.c をC++モ...
*ほんのり多態性の紹介 [#nff24e0f]
例えばこんなクラスを定義(Character.h)したとして
class Character
{
public:
// virtual void Say() = 0; // 一身上の都合により純粋仮...
virtual void Say() { std::cout << "セリフが無いんじゃよ...
};
class Hero : public Character
{
public:
void Say() { std::cout << "悪が栄えた試しなし!" << std...
};
class Zako : public Character
{
public:
void Say() { std::cout << "イー!" << std::endl; }
};
class Boss : public Character
{
public:
void Say() { std::cout << "やっておしまい!" << std::en...
};
こんな感じだね。よく初心者サイトに載ってる例は。
でも、これだと、どんなメリットがあるのか良くわかんないん...
#include<iostream>
#include "Character.h"
using namespace std;
int main()
{
Hero a;
Zako b;
Boss c;
a.Say();
b.Say();
c.Say();
return 0;
}
実行例
c:\>Sample
悪が栄えた試しなし!
イー!
やっておしまい!
ちなみに、こんなことはしちゃだめね。~
#include<iostream>
#include<list>
#include "Character.h"
using namespace std;
int main()
{
Hero a;
Zako b;
Boss c;
list<Character> aryCharacter;
aryCharacter.push_back(a);
aryCharacter.push_back(b);
aryCharacter.push_back(c);
for(list<Character>::iterator iter = aryCharacter.begin...
iter->Say();
}
return 0;
}
-listはSTLに含まれるコンテナで、すさまじく簡単に言ってし...
-iteratorはコンテナにアクセスするためのもので、ポインタみ...
実行例
c:\>Sample
セリフが無いんじゃよ
セリフが無いんじゃよ
セリフが無いんじゃよ
動的生成すると、ちゃんと動作するんだけど、メモリリーク対...
この例ではたった3行だけどね。
#include<iostream>
#include<list>
#include "Character.h"
using namespace std;
int main()
{
Hero a;
Zako b;
Boss c;
list<Character*> aryCharacter;
aryCharacter.push_back(new Hero);
aryCharacter.push_back(new Zako);
aryCharacter.push_back(new Boss);
for(list<Character*>::iterator iter = aryCharacter.begi...
(*iter)->Say();
}
for(list<Character*>::iterator jter = aryCharacter.begi...
delete *jter;
}
return 0;
}
実行例
c:\>Sample
悪が栄えた試しなし!
イー!
やっておしまい!
そしてメモリリーク対策としてスマートポインタ(boostライブ...
(STLにはスマートポインタとしてauto_ptrがあるけど、コンテ...
できたー! って思ってテストしたらなんか動作がおかしい…も...
って思ったのでは、せっかくの多態性の恩恵も台無しだから、...
#include<iostream>
#include<list>
#include<boost/shared_ptr.hpp>
#include "Character.h"
using namespace std;
int main()
{
typedef boost::shared_ptr<Character> pChar;
list<pChar> aryCharacter;
aryCharacter.push_back(pChar(new Hero));
aryCharacter.push_back(pChar(new Zako));
aryCharacter.push_back(pChar(new Boss));
for(list<pChar>::iterator iter = aryCharacter.begin(); ...
iter->get()->Say();
}
return 0;
}
実行例
c:\>Sample
悪が栄えた試しなし!
イー!
やっておしまい!
で、こーなってくると、動的生成部分がもーちょっとなんとか...
戻り値がCharacter*な関数があれば、いろいろ便利になる。
しかし面倒くさくなったので、興味がある人は"[[factory:http...
ググってくれたまえ!
*typeid演算子 [#qeb6122d]
C++では型の情報を表す新しい演算子、typeid が追加されまし...
sizeof と同様にして、typeid(int) や typeid(変数名) のよう...
typeid 演算子が返すのは const type_info& であり、type_inf...
class type_info {
public:
bool operator==(const type_info& rhs) const; // 二つの ...
bool operator!=(const type_info& rhs) const; // 二つの ...
int before(const type_info& rhs) const; // 引数で...
const char* name() const; // 型の名前
const char* raw_name() const; // 型の修...
};
typeid は次のように使います。~
#include <iostream>
//#include <typeinfo> // type_info クラスが宣言されてい...
using namespace std;
class A{};
int main(){
A a, aa;
int b;
cout << typeid(a).name() << endl;
cout << typeid(a).raw_name() << endl;
// a の型と aa の型が等しいか?
if( typeid(a) == typeid(aa) ){
cout << "typeid(a)==typeid(aa)" <<endl;
}
// a の型と b の型が等しいか?
if( typeid(a) == typeid(b) ){
cout << "typeid(a)==typeid(b)" <<endl;
}
return 0;
}
実行結果
class A
.?AVA@@
typeid(a)==typeid(aa)
~
-注意~
--name, raw_name の出力は環境によって変わることがあるので...
--[[Microsoftのリファレンス:http://msdn2.microsoft.com/en...
--gcc の type_info には、raw_name メンバはありません。
*参考サイト [#rb5082c0]
//
// [[オヌヌメサイト]]の項目から一部マージ
//
-[[ロベールのC++教室:http://www7b.biglobe.ne.jp/~robe/...
最初からC++を扱ってます。とはいっても、プログラミングを全...
-[[Programing Place C++編:http://www.geocities.jp/ky_webi...
-[[WisdomSoft -> C++入門:http://wisdom.sakura.ne.jp/progr...
-[[Bjarne Stroustrup: 標準C++を新しい言語として学ぶ:http:...
-[[Stroustrup: C++ Style and Technique FAQ 日本語訳:http:...
-[[豊田孝のIT談話館 標準C++の歴史と哲学>http://www.ttoyot...
// - 復活(確認:2009年08月08日 現在):コンテンツ、サイ...
// - (''注意'' :現在、『豊田孝の「IT談話館」』の初心者...
C++を中心とした知識の基礎固めに。
IT全般に関する記事の他に「VC++ 2005 Express Edition」に関...
--[[Visutal C++ 2005/2008 Express Edition(IDE無料化の背...
無料開発ツール「Visual C++ Express Edition」の活用方法
-[[コンピュータ基礎とプログラミング>http://ipl.sfc.keio.a...
MacOS X,Emacs,g++の環境でC/C++
-[[プログラミングの禁じ手Web版 C++編>http://web.archive.o...
C/C++のコードを書く上でやってはいけないことを列挙したサイ...
サイトが落ちてるのでWeb Archiveで。C MAGAZINEも休刊したし...
-[[More C++ Idioms - Wikibooks, collection of open-conten...
--[[More C++ Idioms - Wikibooks:http://ja.wikibooks.org/w...
-[[ライブラリ リンク コレクション - Cppll:http://www.cppl...
-[[link集/開発言語系/C++ - NomisoBraaan Wiki:http://www.n...
--[[link集/ライブラリ系/C++ - NomisoBraaan Wiki:http://ww...
-[[C/C++ セキュアコーディングセミナー資料 - JPCERT コーデ...
-[[CERT C++ Secure Coding Standard - CERT Secure Coding S...
-[[C++ Reference [C++ Reference]:http://www.cppreference....
--[[C++ リファレンス(日本語版) [C++ Reference]:http://www...
-[[cplusplus.com - The C++ Resources Network:http://www.c...
--[[Documentation:http://www.cplusplus.com/doc/]]
--[[C++ Reference:http://www.cplusplus.com/reference/]]
--[[C++ Sourcecode:http://www.cplusplus.com/src/]]
-[[Visual C++ の勉強部屋>http://homepage3.nifty.com/ishid...
画像処理、電気回路の計算、統計、簡単なGUIなど~
2005、2008、2010
**C++規格 [#d805cd5c]
-[[ISO/IEC JTC1/SC22/WG21 - The C++ Standards Committee:h...
-[[C++ Final Draft International Standard:http://www.kuzb...
-[[日本工業標準調査会:データベース検索-JIS検索:http://ww...
-[[JSA Web Store - JIS X 3014:2003 プログラム言語C++:h...
**STL [#pe9f2fcd]
-[[Standard Template Library プログラミング on the Web:ht...
-[[C++ Standard Template Library [C++ Reference]:http://w...
--[[C++ 標準テンプレートライブラリ [C++ Reference]:http:/...
//--[[C/C++ リファレンス > C++ 標準テンプレートライブ...
-[[角 正史のページ > STLのページ:http://www.wakhok.ac....
-[[ProgramingPlace > C++編(標準ライブラリ):http://ww...
-[[MENISYS-Labo.HP > C++Builder 邪道TIP集:http://orang...
-[[標準 C++ ライブラリ・ユーザーズガイド:http://docs.sun....
-[[Codian>http://www.kab-studio.biz/Programing/Codian/]] -
iostreamについて詳しいサイト。C++自体の解説もありますが、...
-[[S34 > STL samples:http://www.s34.co.jp/cpptechdoc/r...
-[[MSDN > Standard Template Library Samples:http://msd...
-[[MSDN > Standard Template Library Samples:http://msd...
ページ名: