ラボ講座‎ > ‎Visual C++講座‎ > ‎

VisualC++について

CとC++の違い

簡 単に言えば,C言語をオブジェクト指向にしたものがC++言語です.(オブジェクト指向とは何か..という話はここではしません)オブジェクト指向開発と いうのが注目され始めて,C言語を拡張してたものがC++です.ここで注意したいのは,C++という新しい言語を開発されたのではなく,C言語のライブラ リ拡張というスタンスで設計されています.この点は,C言語との互換性を保つ反面,言語として美しくない面があります.一方,JavaやC#は,C言語を 模範にして新しく言語設計されたものですから,オブジェクト指向言語としてはきれいな記述ができます.というわけで,オブジェクト指向プログラミングがで きるという点がCと違います.Javaなどでオブジェクト指向プログラミングを経験しておくと,その違いはわかると思います.

JavaとC++の違い

オ ブジェクト指向プログラミングという考え方は共通です.違いはその書き方です.言語が違えば書き方が違うのはある意味当たり前ですね.両者を比べるとわか りますが,Javaはかなりシンプルな記述です.一方,C++は細かい記述が求められます.簡単に言えば,Javaは高級言語としてかなり大雑把な記述を するだけでプログラムは動きます.一方,C++はオブジェクト指向的な振る舞いを細かく定義する必要があります.

それと,C/C++にはポインタ変数があります.Javaにはありません.ただこれも正確にいえば、C++は
  • C/C++はポインタ変数を言語としてもち,アドレスを意識したプログラミングができる
  • C/C++がポインタ変数持つということはメモリ管理ができる(しなければならない)
ということになります.

Javaは
  • Javaにもポインタ的な概念(いわゆる参照)はあるが,ポインタ変数として細かく扱えない
  • メモリ管理はしなくてよい(VMが解決)
であり、これはC#についても同様です.実はこの話は,WindowsのC++を理解するうえで知っておかないといけないことです.

C/C++とWindowsにおける C/C++の違い

C/C++言語は,様々なOSで使われている一般的なプログラミング言語ですが,WindowsでのC/C++プログラミングを行うには,さらにWindows用のC++ライブラリを理解する必要があります.代表的な例として
  • Win32 API
  • MFC
  • .NETクラスライブラリ (Managed C++/CLI)
があります.MFCは従来から Windowsで使われているC++クラスライブラリです.C/C++用に記述されています..NETクラスライブラリとは,マイクロソフト社の新しい戦 略の元にうまれたライブラリで,C/C++だけでなく他の言語でも使えるクラスライブラリです.

ここで Managed C++/CLIという表現がでてきます.これはどういう意味か?先ほど,C++はメモリ管理しなければいけない...という話を書きまし た.Managed C++とは,メモリ管理しなくてもよいC++を意味します.つまり,C++ をJavaのようにメモリ管理しなくてもいいように言語定義されたものが Managed C++です.Managed C++で書かれたプログラムは,.NETのランタイム上でのみ動きます.つまり,
  • Managed C++/CLI (.NET対応コンパイル)
  • C++ with MFC (ネイティブコンパイル)
ということになります.Visual C++では,従来のC++と Managed C++を混在させることができます.これは最大の利点でもあり,欠点でもあります.欠点というのは、コードがわけわからなくなりますからね.ちょっと話がそれますが,本 来,C++をJava風にしたのがC#だったんですが,Managed C++の出現により,C#の存在意義が薄れかけているという話を耳にします.ま,C#は新言語としてのいい面がありますし、言語としても洗練化されているので、主流にはなると思いますが.

WindowsでC++プログラミングをしようと思ったら,言語としてC/C++を理解するだけでなく,MFC対応のC++とManagedC++/CLIを理解する必要があります.(片方だけでもよい)

データ型について

Windowsプログラミングでは,標準C/C++で定義されている型を別名定義してますので注意してください.
データ型
BOOL TRUE1と定義)またはFALSE0と定義)のブール値。
BOOLEAN TRUE1と定義)またはFALSE0と定義)のブール値。
BYTE 8ビット符号なし整数(unsigned char型/1バイト)
CHAR 文字型(char型/1バイト)
DWORD 32ビット符号なし整数(unsigned long型 )
INT 符号付き整数(int型)
LONG 32ビット符号付き整数(long型)
LONGLONG 64ビット符号付き整数(__int64型/8バイト)
LPBOOL/PBOOL BOOL型へのポインタ
LPBYTE/PBYTE BYTE型へのポインタ
LPCSTR/PCSTR
LPCTSTR/PCTSTR
文字列定数へのポインタ。
LPCVOID あらゆる定数型データへのポインタ。(内容が変更されない)
LPCWSTR/PCWSTR 定数ワイド文字列(Unicode文字列)へのポインタ。(内容が変更されない)
LPDWORD/PDWORD DWORD型へのポインタ
LPHANDLE/PHANDLE HANDLE型へのポインタ
LPINT/PINT INT型へのポインタ
LPLONG/PLONG LONG型へのポインタ
LPSTR/PSTR
LPTSTR/PTSTR
文字列へのポインタ
LPVOID/PVOID あらゆる型のデータへのポインタ
LPWORD/PWORD WORD型へのポインタ
LPWSTR/PWSTR ワイド文字列(Unicode文字列)へのポインタ
PBOOLEAN BOOLEAN型へのポインタ
SHORT 16ビット符号付き整数(short型/2バイト)
TCHAR CHAR型(1バイト)。Unicode版ではWCHAR型(2バイト)。
UINT 符号なし整数(unsigned int型)
ULONG 32ビット符号なし整数(unsigned long型)
ULONGLONG 64ビット符号なし整数(unsigned __int64型/8バイト)
VOID 型なし(void型)。
WCHAR 16ビットワイド文字(Unicode文字)(2バイト)
WORD 16ビット符号なし整数(unsigned short型/2バイト)

 

デバッグメモ

const char [???]' から 'LPCWSTR' に変換できませんというエラーが出た場合は、プログラム側がLPCWSTR型(ユニコード文字列型のポインタ)を要求しているのに、マルチバイトセットの文字列を代入しようとしたことによって発生します。

解決策としては、

  • 各文字列をLPCWSTR型にキャストする
  • プロジェクトをマイルチバイト対応にする

のいずれかです。2005以降はデフォルトでユニコード対応ですので、将来的な方向で考えると、UNICODEで記述したほうがいいと思います。


Comments