気の向くままに辿るIT/ICT
webzoit.netウェブサイトホームページ
プログラミング言語

C++

ウェブ造ホーム前へ次へ
サイト内検索
カスタム検索
C++とは?

C++

UNIX/Linux C++

 1983年に開発されたC++は、「しーぷらすぷらす」日本では「しーぷらぷら」などと呼ばれ、C言語同様UNIXの開発言語としてC言語の良さと時代のニーズを組んだクラスという概念を取り入れた(複雑ではあるものの)比較的人間に理解しやすいオブジェクト指向型プログラミング言語ですが、C++はCと比べても難解で複雑な言語であると云われています。

 C++が難解で複雑である大きな理由の1つは、単にCソースを書くことができる、ある種、素直なCの拡張であるがゆえにプログラマが意識しないとオブジェクト指向アプリケーションを組むことができないこと、その為にはプログラマが膨大なクラスの中から適したものを選別して探し出す必要があることが挙げられます。

C++の派生とGUI用コンパイラ VC++/Objective C++/Borland C++

 C同様C++も多くの環境に移植されているので*BSD/PC-UNIX/LinuxのCUI環境でもWindowsやMacなどのGUI環境でも開発できる環境が整っています。

 当初Microsoft C/C++と呼ばれていたMicrosoft社オリジナルのC/C++は、後にIDE/Integrated Development Environment/統合開発環境であるVisual Studioの下、VC/VC++(Visual C/Visual C++)という品名としてリリースされ、更にVCをVC++に吸収し、VC++に一本化されており、その内、Express版/Visual Studio Expressは無償配布となっています。

 また、Mac OS Xで標準となっているObjective-CというUNIX/Linux Cをベースに上位互換性を持たせたSmalltalk仕様のオブジェクト指向言語があり、UNIX/Linux C++と併用することによってObjective-C++として実装することが可能となっています。

 更に2000年にリリースされ、当時Windows版C/C++コンパイラの無償版も提供されていたBorland社製のBorland C/C++ Builderというコンパイラ付き統合開発環境は、その後、Delphiと共に買収された後、Kylix、C++ Builder X(Java製)、Turbo C++、C++ Builderと変遷があり、Turbo C++とC++ Builderは2007年~2009年の間並行して存在しましたが、その後C++ Builder有償版のみがリリースされているようです。

歴史と共に顕わになったC++の弱点

 C++のベースとなっているC言語はUNIX開発者の1人を中心に開発されUNIXもC言語で書きなおされたといわれているわけですが、そのC言語も開発者によって書かれた書籍及びそのコードの書き方からいわゆるK&Rなどと呼ばれる記法を含め、その内容が数年にわたりデファクトスタンダードとなって後、ANSI Cなどと云われるようにANSI、ISO、JISによって標準化された経緯があります。

 C言語そのものも一応整備された後に未規定や未定義とされている内容を、じっくり見てみると加減乗除の四則演算すら算数と同様に記述するとバグを仕込むことになってしまいかねない意外なケースも数多く、未定義、未規定、処理系定義等々、曖昧な部分も多いので、それまでの常識を疑うことも含めて!?余程、注意深く開発する必要がある言語であり、それをベースとしたC++も同様、更には時の経過と共に何れもセキュリティ上のリスクを排除できるか否かという点や相当に配慮するにしてもその複雑さは明らかです。

 また、Javaの登場により、実際には一長一短はあるもののガベージコレクション機能に注目が集まりました。

 こうした点の多くは、後述のC++/CLIが解消したと言えるでしょう。

.NET Framework対応マネージ拡張C++とCLI対応C++/CLI

 時系列的に前後、また時に併行してMicrosoft社は、.NET Framework(ドットネットフレームワーク)という基盤技術を開発するに至りますが、そのベースをCLIという共通言語基盤として世界標準とすべく技術公開、後にEcmaやISO、その翻訳版としてJISで標準化されています(世界標準化されたJavaScriptはECMAScriptと呼ばれますが、これは通称Ecmaという欧州発祥の標準化団体によって標準化されたものであることを示しています)。

 .NET Frameworkは、中間ファイルとなるアセンブリコードを.NET Framework上でアプリケーションやサービスを動作させるための実行エンジンCLR/Common Language Runtimeで処理できるようにしたことで.NETに対応するプログラミング言語は、OSやハードウェア環境に依存することなく開発が可能となりましたが、これはJavaで言うところのJVM/Java Virtual Machineとバイトコードにあたります。

 こうした背景の中、.NET Frameworkを基盤としたC++は、Managed Extensions for C++/Managed C++/マネージ(ド)拡張C++/マネージドC++と呼ばれ、それまでのC++やVC++の延長線上にありながら、これらとは基盤の異なる言語として別個に誕生しました。

 更にCLIは、.NET Frameworkの更に根源とも言えるもので同等以上の機能を実現するオープンな世界標準であり、CLIに対応すればOSも選ばない、違う言い方をするとJavaの歴史に見られるようにコードを1つ書けば、様々な環境で実行することができ、移植性が高まり、実質.NET対応にもなります。

 そのCLIを基盤としたC++が、世界的に標準化されたプログラミング言語C++/CLIとして誕生しました。

 これにより、それまでのC++をこれらとを区別してアンマネージ(ド)C++やネイティブC++と呼ぶこともあります。

C++/CLIとマネージ拡張C++

 Javaの登場によって、それまでのC++の曖昧さやメモリ解放の問題等々が、より一層、際立ってきたことも手伝ってマネージ拡張C++やC++/CLIも一層その必要性を増したと言えるでしょう(Javaの開発元であるSunがOracleに買収され、Javaの開発者がOracleを離れざるを得なくなった一件は、Javaのイメージダウン以外の何物でもなく、開発されたシステムは右から左へ簡単に移行できるものではないものの、そうした向きもC++/CLIに流れるのではないかと思ったりしなくもありません)。

 マネージド拡張C++以上にC++/CLIの完成度は高く、C++/CLIのコンパイラは、マネージ/アンマネージC++をコンパイルでき、ソース内での混在も可能、クラスなども利用できるので旧ソースなどの資産を活用できますが、新たにC++での開発を考える場合の選択肢は、基本的にC++/CLIとなるでしょうし、その選択が賢明でしょう。

C++/VC++ コンパイラ

 UNIX/Linux C/C++コンパイラには、cc/gcc、更にGNUのgccには、その1つとしてC++用に開発されたg++があり、Windows版のVisual StudioなどGUI統合開発環境には言語及びコンパイラがパッケージ化されています。

 Windows版のGUI統合開発環境も少なくともVisual Studio 2005以降、C・C++・マネージ拡張C++・C++/CLIの統合開発環境となっており、そのソース管理がプロジェクト単位である(関連するソースやその他ファイルはプロジェクトとしてまとめる)ことなどから.vcproj (プロジェクトファイル)があったり、その他、数多くのファイルが用途ごとに存在するので一概に比較することはできませんが、UNIX/LinuxのC/C++を基本として比較してみます。

C++/VC++ ソースファイルの拡張子

ソースファイルの拡張子
UNIX/Linux C++Windows
g++/gcc-3.4.1

gcc-4.1.2
g++/gcc-3.0.2VC++
.C.C.cpp
.cc.cc
.c++.c++
.cp.cp
.cxx.cxx
.cpp.cpp
.CPP

 UNIX/Linux C++とVC++では、より厳密に言うとFSF/GNUのcc/gcc系コンパイラg++とMSのコンパイラVisual Studioの背景と存在、その関係でソースファイルの拡張子が異なります。

 UNIX/Linux CやVCでもソースファイルの拡張子は小文字の.c、VC++では.cppだけですが、gcc(g++を含む)のバージョンによっても多少違いはあるもののUNIX/Linux C++では複数の拡張子が許容され処理できるようになっています。

C++/VC++ ヘッダファイルの拡張子

C/C++/VC/VC++共通
.hヘッダファイル

 ヘッダファイルの拡張子についてはUNIX/Linux C/C++とVC/VC++共に同様です。

 但し、incluedeする場合に若干違いがあります。

 #include <xxx.h> 

 #include "xxx.h" 

 UNIX/Linux C/C++とVC/VC++に共通のincludeとしては、ダブルクォートまたはアングルブラケット< >で括って拡張子付きヘッダファイルを指定します。

 C同様、多くの場合、アングルブラケット< >は標準ライブラリ、ダブルクォート " " はユーザー定義、その他ファイルに利用されます。

 #include <xxx> 

 これに加えUNIX/Linux C++に関しては、アングルブラケット< >を使う場合にヘッダの拡張子.hを省略した記述も許容されます。

 #import <xxx> 

 #import "xxx" 

 VC++、またはC++でwindows.hを取り込むなどWindowsアプリケーションを作成する場合には、#includeではなく#import文を利用する必要がある場合があります。

 #import文もファイルをダブルクォートまたはアングルブラケットで括って取り込むことができ、その意味は#includeと同様ですが、下記リンク先には、VC++について(アングルブラケット<>の場合、環境変数PATH、LIBに設定済みのパス、コンパイル時にIオプションで指定されたパス等)より詳しく書いてあります。

参照:MSDN #import Directive (C/C++)

 リンク先を見ると#importディレクティブは、タイプライブラリから情報を組み込むために使用され、そのタイプライブラリの内容は主にCOMインターフェイスを記述するC ++クラスに変換されるといった旨の記述があります。

C++/VC++ プリプロセスファイルの拡張子

プリプロセスファイルの拡張子
UNIX/LinuxWindows
CC++VC/VC++
.i.ii-

 UNIX/Linux C++とVC++では仕組みが異なるのでUNIX C/C++で言うところのプリプロセスファイルをVC++で出力することは、まず、ありません。

C++/VC++ アセンブラコードの拡張子

アセンブラコードの拡張子
UNIX/LinuxWindows
C/C++VC/VC++
.s-
.S

 UNIX/Linux C/C++で言うところのアセンブラコードは、VC++(マネージ拡張C++、C++/CLI)では、ビルドにおけるファイルの最終形であり、.NET FramworkやCLIが処理する中間コードではありますが、基本的にファイルとして出力されることはありません。

 UNIX C/C++の.sはプリプロセス済みアセンブリファイルの拡張子、.Sはプリプロセスを要するアセンブリファイルの拡張子です。

C++/VC++ オブジェクトファイルの拡張子

UNIX/LinuxWindows
C/C++VC/VC++
.o.o
.obj

 拡張子.oはC/C++/VC/VC++共通ですが、VC/VC++では拡張子.objも認識されます。

 オブジェクトファイルは、オブジェクトモジュールと呼ばれることもあります。

C++/VC++の実行ファイル

実行ファイルの拡張子
UNIX/Linux C/C++VC/VC++
a.out(デフォルト).exe
拡張子の有無を含め
-o コンパイルオプションの
引数となる名前に依存

 UNIX/Linux C/C++では、コンパイルオプションで実行ファイル名を指定した場合は、その名称(慣例、文化的に多くの場合、拡張子は付けない)、指定しなかった場合にはa.outというファイルが実行ファイルとして生成されますが、VC/VC++では実行ファイル名を指定した場合、その名称に拡張子.exeのファイルが、指定しなかった場合にはa.exeが生成されます。

 実行ファイルの違いは、Windowsは拡張子に依存してファイル内容を判断する仕様になっているので例えば実行ファイルは普通は.exeです(MS-DOS環境の.comや起動前設定ファイルには.batもあります)が、UNIX/Linuxでは、拡張子ではなくインタプリタ指定やファイル内容を解析することが前提なので拡張子がないファイルの方がむしろ一般的であり、仮に拡張子と中身が異なったとしても多くの場合ファイル内容によって処理されますし、逆にアーカイブファイルなどのようにxxx.tar.gzといったドット/ピリオドが複数あるファイルさえある環境の違いからくるものです。

 尤もC/C++でも、ある程度拡張子が決まっているファイルにおいては、cc/gcc(g++,gcj)などのコンパイラは、cc/gccコマンドなら入力ファイルは.c、g++なら...、gcjなら...とコンパイラコマンドが何であるかによって入力ファイルを想定し、それら言語においてデフォルトとなっているリンク探索場所などの判定に利用していますが、逆に言うとコンパイルオプションでそれなりに引数を渡せば、例えばgccコマンドでもC++ソースファイル、g++でCソースファイルをコンパイルすることさえできることを意味しますし、それにしても、そもそも拡張子でそのファイル自体の中身を判断しているわけではありません。

 a.outにしてもピリオドとoutの組み合わせは拡張子に見えますし、確かに拡張子という言葉としては合致するかもしれませんが、だからと言って別に拡張子.outで起動するインタプリタやプログラムが存在する(事を期待している)というわけではなく、見やすさ、わかりやすさという視点から、どうせ普通はコンパイルオプションで実行ファイル名を指定するんだし、指定し忘れたか、指定する必要がないと判断した時だけ付けられる仮の名称だから長い名前は考えるのも付けるのも煩わしいし、かと言ってaだけじゃわかりにくいし、もしかしたら名前がかぶるかもしれない、出力はoutputだけどそれじゃ長いよな、それならさoutを拡張子にして、a.outなんてどうだろう?といった意味合いで拡張子が付いているだけ(で妙に説明は長くなりがちですが、ただそれだけのこと)です。

C++/VC++ コメントアウト

 // C/VC/C++/VC++のinclude 
 #include <xxx.h> 
 #include "xxx.h" 

 #include <xxx>  // C++/VC++固有のinclude 

 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 
 C/VC同様< >は標準ライブラリ用に 
 " "はユーザー定義やその他ファイルに 
 利用されることも多い 
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ 

 /* ここからコードを記述 */ 

 コメントアウトは単一行及び複数行のコメントアウトに有効なC/VCのスラッシュとアスタリスクの組み合わせのペア /* */ と、それに加え、C++/VC++では、JavaJavaScript同様、 // スラッシュ2つを単一行用のコメントとして利用することができます。

C/C++のmain関数・VC/VC++の_tmain関数・MFCアプリのWinMain関数

 #include <xxx.h> 
 #include "xxx.h" 
 #include <xxx>   

 // Cのmain関数 
 int main ( int argc , char *argv[ ] ) 
 { 
 ... 
  return 0 ; 
 } 

 OSが存在しないに等しく、利用できるライブラリも環境に依存する組み込み用途などを除き、OSが存在し、C標準ライブラリがある環境において、UNIX/Linux C/C++やObjective-C/C++は実行ファイルを生成するソースファイルに必ず唯一1つのmain関数が必要です。

 但し、VC/VC++にもmain関数やmain関数に当たる関数はあり、必要ですが、(一般的なテキストエディタでソースを書き始める等ではなく)Visual Studioを使うのであればGUI機能を含めたmain関数を自動生成するので修正、追加を除き、自ら作成する必要はありません。

 MFCを使ったWindowsアプリケーションにおいて自動作成されるmain関数は、WinMain関数です。

 #include <windows.h> 

 // VC++の_tmain関数の一例 
 int _tmain ( int argc , _TCHAR* argv[ ] ) 
 { 
  ... 
 } 
 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 
または
 int _tmain ( int argc , TCHAR* argv[ ] , TCHAR* envp[ ] ) 
 { 
  ... 
 } 
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ 

 尚、MFCを利用できないVisual Studio Express含めVC++でPCアプリを作成(windows.hをinclude)する場合は、_tmain関数が生成されるようです。

 また、Visual Studio VC++でウィザードを使ってWindowsフォームアプリケーションを作成する場合には、自動作成されるボディファイルのmain関数は、やはり自動生成されるフォームをコールするように記述されており、IDEのデフォルトでは追加のソースは、そのフォーム名のヘッダ(.h)に記述するという少し違和感のある仕様になっていたりします。

ウェブ造ホーム前へ次へ