- ベストアンサー
C++での <iostream.h>と<iostream>とusingnamespaceの関係等を教えてください。
どうでもいい質問なのですが… C++で色々とソースを打っていると気づいたのです。 #include <iostream.h>とするとusing namespace std;の一文を書かなくてもコンパイルエラーになりません。 また、逆に#include <iostream>とするとusing namespace std;の一文が必要になります。 だから、h(ヘッダファイル)の.hは必要なのかな?と思い、#include <cstdlib.h>とするとコンパイルエラーになります。 なにか理屈がわかりません。コンパイラはVC++6.0です。よろしくご回答の方お願いいたします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
完全な法則、理屈があるというよりも、歴史的経緯によるものです。 <iostream.h>は、namespace stdがまだ決まってなかった頃の名残、「古いヘッダ」です。 VC6は言語仕様が正式に固まるより古い代物なので、 <iostream.h>という過渡期の遺物がついてます。 この頃は、namespace stdがまだなかったので、 <iostream.h>内の関数はusingしなくても使えます。 但し、今の言語仕様ではnamespace stdが導入されてますので、 あくまで互換性のためのものと思います。 新規に書くなら<iostream>を使うべきです。 一方、<iostream>の方は現行言語仕様通りのヘッダです。 こちらは、namespace std内の定義に正しくなっているため、 namespaceを指定して使う必要があります。 using namespace std;や、using std::cout;の他、 std::cout << "foo";などもできますので、 必ずしもusing directiveやusing declarationが必要とは限りませんが。 少なくとも、ヘッダなどで *むやみに* usingはnamespaceの意義を損ない好ましくないと思います(使い方次第)。 > h(ヘッダファイル)の.hは必要なのかな?と思い、 ちなみに、C++としては、単にヘッダであり、ファイルとは限りません。 > #include <cstdlib.h>とするとコンパイルエラーになります。 「c…」なヘッダには原則、対応するC言語のヘッダがあります。 「c…」というヘッダは、そのC言語のヘッダのC++版であり、 もし<cstdlib.h>に相当するものがあるとすれば、それは単に<stdlib.h>です。 C言語にはnamespaceがありませんので、<stdlib.hにもnamespace stdはありません。 <iostream>はC言語にはない、C++独自のヘッダであり、 <cstdlib>はC言語の<stdlib.h>のC++版なので、そのような挙動の違いになります。 <cstdio>と<stdio.h>とか、<cstring>と<string.h>とか、 もともと対応するC言語のヘッダがあるものは「c…」という名前になってます。
その他の回答 (1)
- jacta
- ベストアンサー率26% (845/3158)
すでに出ている回答でおおむね合っていますが、一部補足説明します。 C++では、<stdlib.h>のようなC互換のヘッダは、内部で<cstdlib>を包含しています。すなわち、<cstdlib>で宣言されるstd::absは、<stdlib.h>でもstd::absとして宣言され(すなわち、namespace stdがある)、その上で大域的名前空間でusing std::abs;が行われます。 ただし、これはあくまでも規格上のことであり、古い処理系であるVC++6.0では必ずしもそのようにはなっていません。
お礼
どうもありがとうございます。 単なるstd::の部分も色々な階層があるんですね。一応、Javaをかじっていたのでなんとなくはわかるのですが、まだC++の深い部分まで入っていけません。プロの方からいうと全然深くないかもしれませんが(;^_^ ご回答ありがとうございました。VC6のコンパイラだとちょっとまずいかもしれないので、新たにコンパイラを手に入れたいとおもいます。今はフリーで色々あるのでいいですね。ご回答ありがとうございました。
お礼
丁寧な、ご回答ありがとうございます。 なるほど。<iostream.h>が使われてたころは、「namespace std」が言語仕様で存在しなかったのですね。質問の後、#include <iostream> using namespace std; としたら(.hをつけない)エラーになりました。どうもVC++6.0は、その仕様が決まる前のコンパイラみたいです。 現行の仕様は、おおむね最近の本に書いてあるとおりの書き方なんですね(あたりまえですが(;^^)) 私は、昔買った古い本で色々勉強しています。 尚、ご回答の最後の部分ですが、C++言語を使用している場合、C言語はサブセットとしてふくまれるとの本の記述がありましたが、まさにそのとおりですね。stdlib→cstdlibとかcを付け足しただけですね。 namespaceの使い方とかも色々ありそうですが、次第に勉強を重ね、最適な方法を見つけたいと思います。 どうもご丁寧な回答ありがとうございました。