質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Namespace

各要素の名前の重複による衝突が起こらないよう、一意の名前をつけなければならない範囲のことであり、また、プログラミングにおける識別名を付加する機能のをNamespace(名前空間)と呼ぶ。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

5397閲覧

C++における名前空間内の関数について

torimingo

総合スコア122

Namespace

各要素の名前の重複による衝突が起こらないよう、一意の名前をつけなければならない範囲のことであり、また、プログラミングにおける識別名を付加する機能のをNamespace(名前空間)と呼ぶ。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/12/25 05:54

関数は、基本的にクラスの中に定義するものだと思っていたんですが
以下のように、名前空間内に定義しているコードがありました。
以下のmethod()は、グローバル?に置かれているので
設計的にあまりよくないような気がするのですがどうなんでしょうか?
こういう使い方は問題ないのでしょうか?

namespace AIUEO{
void method();
}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2018/12/25 06:10

確認ですが、その宣言はヘッダファイル内の記述ですよね?
guest

回答4

0

こんにちは。

以下のmethod()は、グローバル?に置かれているので

設計的にあまりよくないような気がするのですがどうなんでしょうか?
こういう使い方は問題ないのでしょうか?

実際に問題がないかどうかは使い方によりますが、グローバル関数=悪ではないです。
適切に使えば善です。間違った使い方をすれば他と同じく悪です。

例えば、C#にはグローバル変数やグローバル関数が一見ないように見えますが、実はstatic変数やstatic関数はそれらと事実上同じものです。しかし、特定のクラスに属さないといけないので時として鬱陶しいです。本質的にクラスと無関係な関数を何かのクラスに属させる意味はないですから。

C++のグローバル関数は「フリー関数」と呼ばれることもあります。クラスに縛られないという意味です。
クラスとの関わりが浅いものは、グローバル関数(フリー関数)で書いた方が良いケースが多いと思います。(他にもグローバル関数を使った方が好ましいケースも多々有ります。)

投稿2018/12/25 06:11

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

torimingo

2018/12/25 06:23

ご回答のほど、ありがとうございます。 グローバルな変数や関数を勝手に悪だと決めつけていましたが、適切な使い方を知らなかっただけだったんですね。 コーディングのときに、変数や関数を無理にでもクラス内に入れていたので、これからは、適切だと思える場面では、グローバルな変数や関数を使っていきたいと思います。
maisumakun

2018/12/25 06:31

極論ですが、C++でもmainはグローバル関数ですから、「それなしに書く」こともできないというオチまであります。
guest

0

method関数は、グローバル名前空間ではなく、AIUEO名前空間にあります。ただし、使い方によっては見かけ上(あくまで見かけ上です)あたかもグローバル名前空間にあるように見える場合があります。

c++

1#include <iostream> 2 3namespace AIUEO{ 4 5 class A {}; 6 7 void method(A a){ 8 std::cout << "OK" << std::endl; 9 } 10 11} // namespace AIUEO 12 13int main(){ 14 AIUEO::A a; 15 method(a); 16 return 0; 17}

これはうまく動きます。これはmethodがグローバル名前空間にあるわけではないですが、ADL(Argument Dependent Lookup)という機能によってこのような記述が可能になります。methodの実引数にAIUEOで定義されたクラスを入れたことが肝です。
ADLは、関数名が何か?とコンパイラが探すとき、実引数の型が定義されている名前空間も含めて探すため、AIUEO::method と書かなくともよくなります。
よく見てください。「<<」を使っていますが、operator<< はstd名前空間で非メンバ関数として定義されています。しかし、ADLのお陰でstd名前空間でなくともcoudがstdで定義されているために std::operator<< が呼ばれているのです。
ADLがないと、演算子のオーバーロードはほとんど使い物になりません。

投稿2019/01/13 14:54

myoon

総合スコア100

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

torimingo

2019/01/13 23:37 編集

ADLという機能ははじめて知りました。 引数に、メソッドと同じ名前空間のクラスを指定すれば、名前空間名は不要で、指定しない場合は名前空間名を明記しなければいけないとは、なんとももどかしい感じがします。 ADLは、特殊な状況で力を発揮するものだと感じました。 一般的なプロジェクトの場合は、わかりやすいように、名前空間名は明記すること、という規約がありそうですね。
myoon

2019/01/14 07:49

ADLによって思わぬ探索が起こる危険もありますから使い方に注意が必用だと思います。 「ADL」「c++」でググると問題点や回避法などがでてきます。例: https://marycore.jp/prog/cpp/about-adl-avoid-adl/
guest

0

グローバル?に置かれている

ではなく、名前空間AIUEOに置かれています。
なので、using namespace AIUEO; 宣言のない場所には不可視になりますd^^

投稿2018/12/25 06:09

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2018/12/25 06:14

AIUEO::method()も有りですね。
torimingo

2018/12/25 06:25

ご回答をありがとうございました。 グローバルと名前空間は違うということを覚えておきます。
cateye

2018/12/25 06:38

変な例えになりますがw operator+()という関数を宣言するときに四角.三角.丸で各々違いが出ると思います。その場合、square、triangle、circleと言う名前空間を使えば一目瞭然d^^
guest

0

ベストアンサー

こういう使い方は問題ないのでしょうか?

はい、全く問題ありません。たとえば、<cstdio>ヘッダーでは、printfなどのC言語から存在する関数群もstd::printfstd名前空間に入れてあります。

投稿2018/12/25 06:02

編集2018/12/25 06:03
maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

torimingo

2018/12/25 06:14

回答のほど、ありがとうございます。関数はクラスのなかに定義するという固定観念がありまして、ある関数を実行するためには、その関数をメンバとするクラスのオブジェクトを持っている必要がある、と思っていました。クラス同士の依存関係を低減するために、デザインパターンなどが広まったのではないのでしょうか。名前空間直下に関数を置くと、どこからでも呼べるようになってしまい、管理の面で問題があると、勝手ながらに思ってしまいます。自分でも頭のなかを整理しきれていないのですが「std::printf」はたしかに名前空間直下に関数がありますね・・。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問