• ベストアンサー

usingの宣言について

C++プログラミングをしているのですが ヘッダファイルに using namespace std; を記入していると、「ヘッダファイルでは書かないこと」 と言われたのですがなぜなんでしょう? 今まで問題なく動いていましたが・・・ 逆にヘッダファイルにこれを書かないと vectorやstringを使用するとき 常に std::vectorやstd::string と書かなくてはいけないような気もするのですが。 誰か教えてください。 お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • phusike
  • ベストアンサー率38% (29/76)
回答No.1

もちろんヘッダだけ見ていれば問題なく動きますよ。 ただし、そのヘッダをincludeしているファイルで、 予期せぬ識別子の衝突が起きる可能性がありますね。 そもそも標準ライブラリで用いられる識別子は、 最初から個人では使うなとするのは一つの選択肢ですが、 名前空間の存在意義というのは、 そもそもそのような衝突を防止するためにあるわけですので、 これでは標準ライブラリをnamespace stdでつつんでいる意味がありません。 ただ、要するにこれはnamespace stdの空間を グローバルに上げてしまうから弊害となるわけであって、 インライン関数や、継承される可能性のないクラス内で、 using namespaceを使うことには特に問題はないと思います。 また、できればusing namespaceで一括指定するのではなく、 使用する識別子のみ個別に using std::vector; 等とするのがよりよいでしょう。

_crystal_
質問者

お礼

宣言スコープの問題なのですね。 ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

基本的なことはすでに回答が出ている通りです。 ただ、それはあくまでも原則論ですので、場合によってはヘッダ内でusing宣言を書くべき状況もあります。それを見極めるには、多くのプログラムに触れることが重要です。 ところで、 using namespace std; というのは、using宣言ではなくusing指令です。 using宣言というのは、 using std::string; のようなものをいいます。

_crystal_
質問者

お礼

ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

ひとことで言えば、常に、std::vector とか std::string とか書かないといけないようにするためです。 もっといえば、この、vector とか、string が、「確かに標準ライブラリに定義してある、vector や string を使いたいので、他のライブラリに存在するものを使うのではない」と明示したいためです。 実際に、vector や string という有名な名前なら、わざわざ標準ライブラリと同じ名前を使うことはないと思いますが、std ではない、何かのライブラリを使ったときに、同じように、open() を使っていたというようなことはありそうですから。 蛇足ですが、「今まで問題なく動いていましたが」は禁句です。 ・今まで動いていたけど明日も動くと(または、他のマシンでも動くと)保証できるような書き方なのか ・単に「動く」レベルなのか、「よりより書き方」なのか(今回のはこちら) などなど、「今まで問題なく動いていた」けど、だめなコードというのは、よくあるのです。 プロなら or プロを目指すのなら、「今まで動いていた」は禁句としましょう。

_crystal_
質問者

お礼

「今まで動いていた」を信じなければ プログラムの何を信じるとの考え方もありそうですが 単純プログラムだけにこのように考えていました。 ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • using namespace std;//?

    nubou C++で using namespace std; という宣言が使えるということなのですが ・namespaceとはなんでしょうか? ・stdとはなんでしょうか? ・このような宣言が必要な場面はどのようなときなのでしょうか? いずれかひとつでも結構です (質問に間違いがありましたので修正しました) よろしくお願いします

  • 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です。よろしくご回答の方お願いいたします。

  • プログラミング言語Cとプログラミング言語C++

    プログラミング言語Cとプログラミング言語C++の違いって何ですか? あと、プログラミング言語C++についていくつか質問があります。 #include <iostream> using namespace std; void main(){ cout << "Hello world!" << endl; } このプログラムについて質問なんですが、iostreamってプログラミング言語Cで言うstdio.hのことですか? using namespace stdって何ですか? あと、 cout <<"Hello world!"って何ですか?

  • C++のnamespace stdについて

    C++のnamespace stdについて教えて下さい。 coutを使用する場合"iostream"をインクルードし、using namespaceでstd名前空間を使用します。 printfを使用する場合"cstdio"をインクルードし、using namespaceでstd名前空間を使用します。 どちらのインクルードファイルにもnamespace stdという風に同じ名前の名前空間を 使用しているのでしょうか? もしもそうだとしたらcstdio,iostreamの両方をインクルードしている場合 名前空間が競合してしまうのではないでしょうか? namespaceはjavaでいうパッケージにあたる物だと思っていたので、 これでは意味がないのではないかと思いました。 それとも意図的に同じ名前空間を定義している意味があるのでしょうか? C++を使い始めたばかりで戸惑っています。どなたかお答え頂ければありがたいです。

  • Vectorのポインタが入ったvector

    windows Vista sp1, Visual C++ 2008でC++の勉強をしています。 Vectorへのポインタが入ったvectorを使うプログラムを書いているのですがうまくいかず、困っています。 どういうプログラムかというと、 入力ファイルの">"という記号を区切りとして、その間にある各行をひとまとめのグループとしてvectorにいれます。 さらに各vectorのポインタをべつのvectorに入れます。 最終的に区切りの数だけvectorができ、入力ファイルを読み終わった後に すべてのvectorを"各グループのポインタが入ったvector"からループ処理ですべて出力する、というものです。 /入力ファイル input.txt/ > human cat dog > beetle dragonfly spider > salmon saury catfish > vector1には human cat dog vector2にはbeetle dragonfly spider vector3にはsalmon saury catfish が入り、 別のvectorにそれぞれのvectorのポインタをいれ、 最後にこのvectorをつかって全ファイル内容を出力するというものです。 具体的に書くと、 ">"の区切りごとの各行のstringを入れるvectorとしてeach_vector。 each_vectorのポインタを入れるvectorをvector_of_ptr_each_vectorとします。 ">"を認識するごとに new で each_vectorの領域を確保し、そのポインタをvector_of_ptr_each_vectorに追加していき、">"のない行のstringを each_vectorに入れます。 ファイルの読み込みが終わった後でvector_of_ptr_each_vectorからイテレータを使って各vector(each_vector)の全要素をそれぞれ出力する、というものです。 以下のようにコードを書きました。 #include <fstream> #include <string> #include <vector> #include <iostream> using namespace std; int main( ) { ifstream ifs("input.txt"); string buf; std::vector<string> each_vector; std::vector<std::vector<string> *> vector_of_ptr_each_vector; while(ifs && getline(ifs, buf)) { if(buf[0] == '>'){ std::vector<string>* ptr_eachvector ; ptr_eachvector = new std::vector<string>; each_vector = *ptr_eachvector ; vector_of_ptr_each_vector.push_back(ptr_eachvector) ; } each_vector.push_back(buf) ; } printf("\n output from vector of ptr of vector\n"); std::vector<std::vector<string> *>::iterator it_b = vector_of_ptr_each_vector.begin(); while( it_b != vector_of_ptr_each_vector.end() ) { std::vector<string>::iterator it_c = it_b->begin();    //エラー1 while( it_c != it_b->end() ) //エラー2 { cout << *it_c << endl; ++it_c; } ++it_b; } return 0; } ですが、エラーでビルドされず、 std::vector<string>::iterator it_c = it_b->begin(); の行に関して error C2839: invalid return type 'std::vector<_Ty> **' for overloaded 'operator ->' error C2039: 'begin' : is not a member of 'std::_Vector_iterator<_Ty,_Alloc>' while( it_c != it_b->end() )   の行に関して error C2839: invalid return type 'std::vector<_Ty> **' for overloaded 'operator ->' 1> with 1> [ 1> _Ty=std::string 1> ] error C2039: 'end' : is not a member of 'std::_Vector_iterator<_Ty,_Alloc>' 1> with 1> [ 1> _Ty=std::vector<std::string> , 1> _Alloc=std::allocator<std::vector<std::string> > 1> ] fatal error C1903: unable to recover from previous error(s); stopping compilation というようなエラーが出ます。 vectorのポインタを入れたvectorの扱い、特にイテレータに関して問題があると思うのですが原因が分かりません。 また、new でのeach_vectorの領域確保の方法も怪しいという感じがします。 解決策、アドバイスありましたらよろしくお願いします。

  • C++.NET の String型の使い方

    初めて質問いたします。 C++ .NET 2005 Express Beta版を入手し、Windows Formsのプログラミングを勉強してます。 TextBoxのTextに値を変数で指定したいのですがどうすれば良いのかわかりません。   textBox1->Text = "Test"; とダイレクトに値を指定すればできるのですが、   #include <string>   using namespace std;    (省略)   string str = "Test";   textBox1->Text = str; は、エラーになってしまいます。 C++標準のstringクラスではなく、.NETはStringクラスがあるようですが、これの使い方がMSDN等で調べているのですが分かりません。 分かりやすいURLなどありましたら教えていただけませんか。

  • C++/CLI 関数がインポートできない

    Visual C++でビルドすると、 1>ConnectionWrapsTest.cpp(12): warning C4679: 'ConnectionWraps::Class1::GetConnection' : メンバーをインポートできませんでした 1> 型 'ConnectionWraps::Class1 ' をアセンブリ 'ConnectionWraps, Version=1.0.4594.40998, Culture=neutral, PublicKeyToken=null' からインポート中に、この診断が発生しました。 という様なエラーがいくつかでて、失敗してしまいます。 何故この様なエラーが出るのか理解出来ません。解決策を教えてください。 DLL側 ------------------------------------------- // ConnectionWraps.h #pragma once using namespace System; using namespace std; #include <string> namespace ConnectionWraps { public ref class Class1 { // TODO: このクラスの、ユーザーのメソッドをここに追加してください。 public: static int GetConnection(string address, string port, string database, string userid, string password); static void CloseConnection(int handle); static int ChangeDatabase(int handle, string databaseName); static int Command(int handle, string sql); }; } -------------------------------------------------- 実行ファイル側 ---------------------------------------------------- // ConnectionWrapsTest.cpp : メイン プロジェクト ファイルです。 #include "stdafx.h" #include <string> using namespace std; using namespace System; using namespace ConnectionWraps; int main(array<System::String ^> ^args) { Console::WriteLine(Class1::GetConnection("a", "a", "a", "a", "a", "a")); return 0; } -------------------------------------------------

  • この文章正確ですか?

    #include <string> #include <iostream> using namespace std; int main(){ string s1; s1 = "こんにちわ"; count << s1 << endl; } これをコンパイルしようとしてもできません。 どこが間違っているのでしょうか?

  • C++

    C++で書いた下記のプログラムが、文字の入力が1023個までなら実行されますが、1024個を超えると実行されません。なぜだか分かる方、教えてください。 #include <iostream> #include <string> using namespace std; int main(void) { string Str; cin >> Str; cout << "here"; }

  • 【C++】ヘッダ内でstringを格納する変数の宣

    【C++】ヘッダ内でstringを格納する変数の宣言ができない 下記クラスのように、string型の変数nameを宣言したいのですができません。 どのようにしてstring型データを格納する変数を宣言すればよいのでしょうか? //--------------- //Neko.h #pragma once #include <string> ref class Neko { private: string name; public: Neko(); }; //--------------- //Neko.cpp #include "StdAfx.h" #include "Neko.h" #include <string> using namespace std; Neko::Neko(){ name = "neko"; }

このQ&Aのポイント
  • EP-315でスマホから簡単にレーベル印刷する方法を教えてください。
  • スマートフォンのOSがAndroidで、EP-315のレーベル印刷方法がわからないので、詳しい手順を教えてください。
  • EP-315の使い方についてはわかるのですが、スマホからのレーベル印刷方法が分からず困っています。お手数ですが、教えていただけると助かります。
回答を見る