namespace , extern , include について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
shinpei

namespace , extern , include について

#1

投稿記事 by shinpei » 13年前

Dxライブラリで使う画像を Image という名前空間にまとめるために次のように書きました。

Image.h

コード:

namespace Image{
	extern const int graphics;
}
Image.cpp

コード:

#include "Image.h"
#include "DxLib.h"

const int Image::graphics = LoadGraph("graphics.png");
こうすることで、 Image.h を include すれば Image::graphics にアクセスできるようになったのですが、 graphics の値が-1(読み込み失敗)になってしまいます。
名前空間に extern const int test を加え、 image.cpp で test = 5 とすると上手くいき、また WinMain 関数内で同じように graphics.png を読むのも上手くいきます。
const を外しても同じでした。

なぜ名前空間内では失敗するのですか?

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: namespace , extern , include について

#2

投稿記事 by beatle » 13年前

graphics変数をグローバル領域で初期化しようとしていますね。
グローバル領域での初期化はmain関数の実行より先に行われるため、DxLib_Init関数の実行よりも先にLoadGraphが実行されてエラーになっていると思います。

shinpei

Re: namespace , extern , include について

#3

投稿記事 by shinpei » 13年前

なるほど…
load(){ Image::graphics = LoadGraph("graphics.png"); Image::test = LoadGraph("test.png"); ... }
というものを作り、DxLib_Init関数の実行後に呼ぶと読み込めました。

graphics や test を const にするにはどうすればよいのですか?

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: namespace , extern , include について

#4

投稿記事 by h2so5 » 13年前

初期化タイミングを制御したい場合にconstは使えないので、関数を使用してアクセス制御をする方法があります。

コード:

namespace Image {
    // ロード
    extern void Load();

    // 読み取り専用
    extern int get_graphics();
    extern int get_test();
}

コード:

namespace Image {

    // 外部からのアクセスを禁止
    namespace {
        int graphics;
        int test;
    }
    
    void Load()
    {
        graphics = LoadGraph("graphics.png");
        test = LoadGraph("test.png");
    }
    
    int get_graphics()
    {
        return graphics;
    }
    
    int get_test()
    {
        return test;
    }
}

shinpei

Re: namespace , extern , include について

#5

投稿記事 by shinpei » 13年前

やはり const にするのは初期化のタイミング的に無理ということですね
教えていただいたように関数の戻り値から得ることにします

ところで、それならこうしても良いですよね?

コード:

class Image{
privete:
	static int graphics;
	
public:
	int get_graphics(){
		return graphics;
	}
}
定数をまとめる時、クラスと名前空間のどちらを使うのが適切なのですか?

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: namespace , extern , include について

#6

投稿記事 by h2so5 » 13年前

クラスを名前空間のように使う場合、これでは不十分です。
shinpei さんが書きました:

コード:

class Image{
privete:
	static int graphics;
	
public:
	int get_graphics(){
		return graphics;
	}
}
インスタンス生成を禁止するためにコンストラクタをprivateにしていますが、名前空間を使う場合よりも少し冗長になります。
機能的にはクラスを使っても名前空間を使っても同じです。

コード:

class Image{
private:
    Image();

private:
	static int graphics;
	
public:
	static int get_graphics(){
		return graphics;
	}
}
ただ、画像データのロードや参照などの機能をこのようなモノステートパターンで実装するのは良い設計とは思えません。
DXライブラリの関数は実行出来るタイミングが限定されているので、グローバルスコープからどのタイミングでもアクセスできる設計になっているとバグの原因になると思います。

shinpei

Re: namespace , extern , include について

#7

投稿記事 by shinpei » 13年前

ありがとうございました

閉鎖

“C言語何でも質問掲示板” へ戻る