• ベストアンサー

特定のクラスだけで const 変数を有効にしたい

円周率のような “意味を持つ定数” を C++ では以下のようにするのをよく見かけます。 const double PI = 3.1415926; これを特定の 1 つのファイル内だけで有効にする方法はありませんか? 例えばあるクラス Hoge.cpp と Hoge.h のみで上記の PI を使う,というように。 Hoge.h をインクルードするファイルにおいては PI を無効にしたいのです。 C++ 超初心者につき,マヌケな質問をしているかもしれないですが,ご教授願えたら幸いです。

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

  • ベストアンサー
  • clsdi99
  • ベストアンサー率63% (31/49)
回答No.4

こんな感じは如何でしょう? class Hoge {  enum {N = 3};  double x[N][N]; ...

k1220011_2005
質問者

お礼

回答くださり,ありがとうございます。

その他の回答 (4)

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

#1です。 今回のケースであれば、#3または#4の回答のように、Hogeクラスの非公開部で定義してやれば十分かと思います。 なお、扱いたい定数というのが、整数の場合とそれ以外の場合では、かなり事情が異なりますので、ご注意ください。

k1220011_2005
質問者

お礼

回答くださり,ありがとうございます。 > なお、扱いたい定数というのが、整数の場合とそれ以外の場合で 今後の勉強の道しるべになります。ありがとうございます。

回答No.3

#1の補足の例なら、これでも宜しいかと。 class Hoge {   static const int N = 3;   double x[N][N] public: //以下略 尚、staticにしてはいても実際にメモリ空間を消費することはありません。

k1220011_2005
質問者

お礼

回答くださり,ありがとうございます。 メンバ変数内で上述のような定義ができることを知り,勉強になりました。 便利そうな記述なので今後,使う機会をさぐっておきます。

  • sonetea
  • ベストアンサー率26% (9/34)
回答No.2

Hoge.cppの方で宣言してください。 他のファイルでもPIの宣言がある場合などを考慮すると namespace { const double PI = 3.1415926; } と記述するのが良いと思います。 無名名前空間というものです。

k1220011_2005
質問者

お礼

回答くださり,ありがとうございます。 名前空間について 20 分ほど本を読みました。 よい勉強になりました。今後の技術として蓄えておきます。

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

Hoge.hとHoge.cppにはどんな内容が記述されますか? また、PIはどのような使われ方をされますか?

k1220011_2005
質問者

お礼

補足をつけてみたら,欲しかった回答が得られました。 質問の仕方も勉強できてよかったです。ありがとうございました。

k1220011_2005
質問者

補足

質問では便宜上,変数 PI としましたが,PI でなく整数 N で以下のようなことをしたいと思っています。 例えば 3 つのファイル Hoge.h と Hoge.cpp と main.cpp があるとして… /**  * Hoge.h  */ const double N = 3; class Hoge {   double x[N][N] public:   返り値 1  関数 1 ( 引数 1 ) { 処理 1  }   返り値 2  関数 2 ( 引数 2 ) { 処理 2  } }; /**  * Hoge.cpp は省略(すべてヘッダファイル Hoge.h に書くとして)  */ /**  * main.cpp  */ #include "Hoge.h" int main() {    Hoge h;    return 0; } のような構成とします。 const 変数 N はクラス Hoge の中で配列の大きさを決めるためだけに使いたいのです。 他のファイルたとえば main.cpp に const 変数 N のスコープが及んでほしくないのです。 つたない説明ですが,補足させていただきます。

関連するQ&A

  • const char*のグローバル変数として使うのはどうしたら良いでし

    const char*のグローバル変数として使うのはどうしたら良いでしょうか? 以下のような動作を実装しようとしています。 mainからデータファイルの値を読み込みます。 その際、読み込むデータファイルのファイル名は別のコンフィグファイルに記載されているので、コンフィグから、データファイルのファイル名を読み込んで、データファイルをオープンする必要があります。 これをファイルを分割して実装しているのですがうまくいきません。 説明のため、データファイル名をmainから出力する実際と同じファイル構成のコードを作成しました。 以下のように5つのファイルに分けています。この際、データファイルのファイル名をconst char* filenameとしています。 ソースファイル #1: main.cpp //util.cppでfilenameに設定されたファイル名を表示する。 ソースファイル #2: set_filename.cpp //グローバル変数であるfilenameにコンフィグファイルに記載されているファイル名を設定する関数が定義されています。 ヘッダファイル #1: etc.h   //filenameの宣言が記載されていて、main.cpp, set_filenameでincludeされている。 ヘッダファイル #2: global.h //filenameの定義が記載されている。 ヘッダファイル #3 : set_filename.h //set_filename.cpp関数のプロトタイプ宣言 このような場合、set_filename.cpp内の関数で設定したfilenameがmain内で違う値に変わってしまいます。下のソースの例では、data.txtと出力されるのが期待値ですが、ゴミ値が表示されます。環境はVisual C++ 2008です。 どうして、set_filenameで設定したファイル名が変わってしまうのでしょうか? また、所望の動作はどのようにソースを変えれば実装できるのでしょうか? サンプルのソースは以下のとおりです。 -----main.cpp---------------- #include "etc.h" #include "global.h" #include "util.h" using namespace std; void main() { ifstream ifs("config.txt"); set_filename(ifs);  //config.txtには「data.txt」と記載しています。 cout<<filename<<endl; } -- ---------set_filename.cpp------- #include "etc.h" #include "util.h" void set_filename(ifstream &ifs) { string temp; ifs>>temp; filename=temp.c_str(); cout<<filename<<endl; ifs.close(); } ---- ---------etc.h----------------- #include <fstream> #include <cstdio> #include <string> #include <iostream> extern const char* filename;  //データファイル名です。 -- ----global.h-------- const char* filename; -- ----set_filename.h--- using namespace std; void set_filename(ifstream &ifs); --

  • C言語、円周率の値が0.000000?

    いつも大変お世話になりありがとうございます。 下記のコードを実行したところ、円周率の値が0.000000になりました。 どうしてでしょうか? アドバイスの程宜しくお願い申し上げます。 #include <stdio.h> int main(void) { double pi; printf("円周率の値はいくつですか?\n"); scanf("%1f", &pi); printf("円周率の値は%fです。\n", pi); return 0; } C:\MinGW>Sample9 円周率の値はいくつですか? 3.14 円周率の値は0.000000です。

  • c++ クラスに関してです。

    うまくクラス同士を連動させることができなくてエラーが出てしまいます。 どこが間違えているのかアドバイスくださると助かります。 #ifndef H22_H_ #define H22_H_ #include <string> #include "account.h" class Bank { public: Bank(); void deposit(double amount, const std::string& accountType); void withdraw(double amount, const std::string& accountType); void transfer(double amount, const std::string& accountType); double getBalance() const; double getSavingsBalance() const; double getCheckingBalance() const; private: Account checking, savings; }; #endif #ifndef ACCOUNT_H #define ACCOUNT_H #include <string> #include "account.h" class Account{ public: Account(); Account(double &amout); double deposit(double amount); double getBalance() const; double withdraw(double amount); double balance; private: }; #endif #include <iostream> #include "acount.h" using namespace std; Account::Account { balance = 0; } Account::Account(double amount) { balance = amount; } Account::double deposit() const { return balance; } Account::double getBalance(double balance) { balance += amount; return balance; } Account::double withdraw(double amount) { if(amount > balance) { balance -= 5; return balance; } elese { balance -= amount; return balance; }} h22.h の中身 #include <string> #include "h22.h" #include "account.h" #include <stdexcept> using namespace std; Bank::Bank() { Account checking; Account saving; } void Bank::deposit(double amount, const string& accountType) { if (accountType != "S" && accountType != "C") throw invalid_argument("Does not compute"); else if(accountType == "S") savings.balance += amount; else if(accountType == "C") checking.balance += amount; } void Bank::withdraw(double amount, const string& accountType) { if (accountType != "S" && accountType != "C") throw invalid_argument("Does not compute"); else if(accountType == "S") savings.balance -= amount; else if(accountType == "C") checking.balance -= amount; } void Bank::transfer(double amount, const string& accountType) { if (accountType != "S" && accountType != "C") { throw invalid_argument("Does not compute");} else if(accountType == "S") { savings.balance += checking.balance; savings.balance = 0;} else if(accountType == "C") { checking.balance += amount; checking.balance = 0;} } double Bank::getBalance() const { return getBalance(); } double Bank::getSavingsBalance() const { return savings.getBalance(); } double Bank::getCheckingBalance() const { return checking.getBalance(); } メイン.cpp http://pastebin.com/rQTj8xciです。 なにかヒントやアドバイスお願いします

  • 多くのファイルで共通で使う数(C++)

    現在大学の卒業研究でこんな感じのプログラムをC++で作っているのですが ちょっと行き詰っています。 動くには動くのですが、汚いというか。 main.cpp --->実験プログラムのメイン。実験の初期値などが書いてある。 basic.cpp --->基本的な算術計算につかう関数やデータ構造のクラスが書いてある。 sampling.cpp learning.cpp --->実験にいろいろ使うメソッドが書いてある。 これらに加えてbasic.h, sampling.h, learning.hがあり それぞれのcppファイルにインクルードしてあります。 また各cppファイルに共通で使う定数があるのです。たとえば const int DIMENSION = 3; //3というのはたとえばで実験の条件による違う const int ROOP = 20000; などという感じです。これをmain.cppの先頭で宣言して condition.hにextern const int DIMENSION;などと書いて 各cppファイルにこれまたインクルードさせてあります。 今のところこれはこれでプログラムは問題なく動いているのですが 今になって仕様を少し変更する必要が出てきました。 たとえばこのcppファイル群をzikkouという実行ファイルに コンパイルしていたとすると、実行の際に $ zikkou 4 20000 という感じに引数としてDIMENSION,ROOPの値を指定したいのです。 ($はプロンプト画面、ターミナル画面ということです) constのままだとこのように実行の毎にDIMENSION,ROOPを変更するというのは出来ないと思うんですが constを外すと、実行中の安全性が疑問です。 (これらの定数は一回ある値でプログラムが動き出したら絶対に 変わりませんし変わってはいけません) なにか良い方法はございませんでしょうか? よろしくお願いいたします。 なにか情報不足がありましたらおっしゃってください。 すぐに補足いたします(ソースのupは長すぎて難しいです)。 よろしくお願いいたします。

  • ヘッダーファイルのインクルード

    VC++6.0です。 ヘッダーファイルをincludeしていいかどうかは どのように決まるのでしょうか? classは、appとhogeの1種類があるとして、 app.h、app.cppとhoge.cpp、hoge.hの4つのファイルがあるとします。 1)appによるhogeのメンバの操作があって、その逆は無い場合 2)hogeもappのメンバを操作する場合 のそれぞれで教えてください。 最初、私は、そのclass内で別のclassのメンバ関数を 呼ぼうと呼ぶまいとincludeしてもかまわないと思っていました。 しかし、自分の作ったプログラムを検討したところ 1)の場合で、hogeのヘッダーに #include "app.h"と入れるとエラーになります。 hogeのcppファイルに#include "app.h"と入れてもエラーになります。

  • [C++]const int と配列

    constについて教えてください。以下のコード //------------------------------------------------------ #include <stdio.h> #include <math.h> const double RANGE = 12.; const int MESH = 10; //const int N = (int)(12.0*10); // (1) OK //const int N = (int)(12.0*MESH); // (2) OK const int N = (int)(RANGE*10); // (3) NG //const int N = (int)rint(12.0*10); // (4) NG double Array[N]; //------------------------------------------------------ をg++ 4.0.1でcompileすると error: array bound is not an integer constant とでてきます。(1)(2)ではエラーは出ません。 (1)(2)が良くて、(3)がだめな理由がわかりません。 どなたか教えてください。

  • 初めてのC言語 

    半径rで円周をだすプログラムを作りたいのですが作ってみたところ答えが0.00しかでてきません。 どこが間違っているのでしょうか。 #include <stdio.h> #define PI 3.14159265358979 /* 円周率 */ int main(void) { double r,a; printf("r="); scanf("%lf",&r); a=r*2*PI; printf("r*2*PI=%5.2lf\n",a); return 0; }

  • ヘッダファイルの有効範囲

    現在OpenGLを使ったプログラムを作っていて, hoge.hというヘッダファイルで #include <GL/glut.h> piyo.hというヘッダファイルには #include "hoge.h" そしてさらにhogehoge.hというヘッダファイルに #include "piyo.h" として, hogehoge.cppのソースファイルにて #include "hogehoge.h"してOpenGLの関数を使おうとしたら エラーが出ました. hogehoge.cppでhogehoge.hをインクルード →hogehoge.hでpiyo.hをインクルード →piyo.hでhoge.hをインクルード →hoge.hでGL/glut.hをインクルード というように,橋渡し的にインクルードはできないのでしょうか? これはこのような仕様なのでしょうか? それとも他に誤りがある可能性があるのでしょうか… 非常に困っております. ご回答お待ちしております.

  • C++ iteator const を使ったプログラムがコンパイルできない

    以下のプログラムがコンパイルできません。 理由もよく分かりません。 ----------------- #include <algorithm> #include <list> struct Hoge { std::list<Hoge*> l; Hoge * f() const { std::list<Hoge*>::iterator i = l.begin(); return 0; } }; -------------------- g++ 4.1.1 を使っていますが % g++ -c test1.cc test1.cc: In member function 'Hoge* Hoge::f() const': test1.cc:8: error: conversion from 'std::_List_const_iterator<Hoge*>' to non-scalar type 'std::_List_iterator<Hoge*>' requested となります。 l.begin() が const で代入できないということだと思うのですが std::list<Hoge*> l; の部分には const を使っていませんし良く分かりません。 また、 Hoge * eval() const { の const を消すか、 std::list<Hoge*>::iterator i = l.begin(); の代入をやめると コンパイルが通ります。 const は return するポインタの先の領域を変更不可にしている と解釈しているのですが、戻り値と関係ない代入がどうして影響を受けるのかが謎です。 (実際は、もう少し違う大きいプログラムですが関係なさそうな部分を削って 上でも同様のエラーメッセージが出ることを確認しました。)

  • .NET言語の定数について

    記述の違い以外は.NETの言語共通の質問になるのですが、 質問はC#で質問いたします。 定数を表すのに const double PI = 3.14; static readonly double PI = 3.14; などと2つの書き方があるようですが、使い分けの 仕方がわかりません。 どのような場合に、どちらを使うものなのでしょうか?