ページ 11

C++でクラス内の関数と同名の標準関数の呼び出し

Posted: 2011年1月18日(火) 16:31
by みけCAT
開発環境はDev-C++4.9.9.2、gcc3.4.2です。
C++で、クラス内で定義した関数と同名の標準関数を呼び出すことはできますか?
たとえばこのソースをコンパイルすると

コード:

#include <stdio.h>

class TestClass {
	private:
		FILE* aaa;
		char testtest[100];
	public:
		static const int OPEN_BINARY=1;
		static const int OPEN_TEXT=2;
		
		int fopen(const char* filename);
		int load(int mode);
		int save(int mode);
};

int TestClass::fopen(const char* filename) {
	//ダミー
	return 0;
}

int TestClass::load(int mode) {
	if(mode!=OPEN_BINARY && mode!=OPEN_TEXT)return 0;
	aaa=fopen("load.txt",mode==OPEN_BINARY?"rb":"r");//エラー 
	if(aaa==NULL)return 0;
	fgets(testtest,sizeof(testtest),aaa);
	fclose(aaa);
	return 1;
}

int TestClass::save(int mode) {
	if(mode!=OPEN_BINARY && mode!=OPEN_TEXT)return 0;
	aaa=fopen("save.txt",mode==OPEN_BINARY?"wb":"w");//エラー 
	if(aaa==NULL)return 0;
	fprintf(aaa,"%s",testtest);
	fclose(aaa);
	return 1;
}

int main(void) {
	TestClass test;
	test.load(TestClass::OPEN_TEXT);
	test.save(TestClass::OPEN_BINARY);
	return 0;
}

コード:

D:\(中略)\classtest.cpp: In member function `int TestClass::load(int)':
D:\(中略)\classtest.cpp:23: error: no matching function for call to `TestClass::fopen(const char[9], const char*)'
D:\(中略)\classtest.cpp:16: note: candidates are: int TestClass::fopen(const char*)

D:\(中略)\classtest.cpp: In member function `int TestClass::save(int)':
D:\(中略)\classtest.cpp:32: error: no matching function for call to `TestClass::fopen(const char[9], const char*)'
D:\(中略)\classtest.cpp:16: note: candidates are: int TestClass::fopen(const char*)
というエラーが出ました。
実際はクラスのfopen関数もそれなりに実装されています。
この場合クラス内のfopenではなく、標準関数のfopenを呼び出したいのですが、そのようなことはできますか?
もしできるなら、その方法を教えていただければ幸いです。
できないのであれば、できないと言っていただければかまいません。
よろしくお願いします。

Re: C++でクラス内の関数と同名の標準関数の呼び出し

Posted: 2011年1月18日(火) 16:36
by Blue
::fopen としたらどうでしょうか?

Re: C++でクラス内の関数と同名の標準関数の呼び出し

Posted: 2011年1月18日(火) 16:45
by みけCAT
うまくいきました。
ありがとうございます。

コード:

#include <stdio.h>

class TestClass {
	private:
		FILE* aaa;
		char testtest[100];
	public:
		static const int OPEN_BINARY=1;
		static const int OPEN_TEXT=2;
		
		int fopen(const char* filename);
		int load(int mode);
		int save(int mode);
};

int TestClass::fopen(const char* filename) {
	//ダミー
	return 0;
}

int TestClass::load(int mode) {
	if(mode!=OPEN_BINARY && mode!=OPEN_TEXT)return 0;
	//aaa=fopen("load.txt",mode==OPEN_BINARY?"rb":"r");//エラー
	aaa=::fopen("load.txt",mode==OPEN_BINARY?"rb":"r");
	if(aaa==NULL)return 0;
	fgets(testtest,sizeof(testtest),aaa);
	fclose(aaa);
	return 1;
}

int TestClass::save(int mode) {
	if(mode!=OPEN_BINARY && mode!=OPEN_TEXT)return 0;
	//aaa=fopen("save.txt",mode==OPEN_BINARY?"wb":"w");//エラー
	aaa=::fopen("save.txt",mode==OPEN_BINARY?"wb":"w");//エラー
	if(aaa==NULL)return 0;
	fprintf(aaa,"%s",testtest);
	fclose(aaa);
	return 1;
}

int main(void) {
	TestClass test;
	test.load(TestClass::OPEN_TEXT);
	test.save(TestClass::OPEN_BINARY);
	return 0;
}

Re: C++でクラス内の関数と同名の標準関数の呼び出し

Posted: 2011年1月18日(火) 16:55
by ゆーずぃ
解決したようですが念のため。
標準関数はstd名前空間に収められているので、明示的に書くのであれば std::hoge と書くと分かり易くて幸せになれるかも。

Re: C++でクラス内の関数と同名の標準関数の呼び出し

Posted: 2011年1月18日(火) 17:06
by みけCAT
stdを付けるとエラーが出ました。

コード:

#include <stdio.h>

class TestClass {
	private:
		FILE* aaa;
		char testtest[100];
	public:
		static const int OPEN_BINARY=1;
		static const int OPEN_TEXT=2;
		
		int fopen(const char* filename);
		int load(int mode);
		int save(int mode);
};

int TestClass::fopen(const char* filename) {
	//ダミー
	return 0;
}

int TestClass::load(int mode) {
	if(mode!=OPEN_BINARY && mode!=OPEN_TEXT)return 0;
	//aaa=fopen("load.txt",mode==OPEN_BINARY?"rb":"r");//エラー
	//aaa=::fopen("load.txt",mode==OPEN_BINARY?"rb":"r");
	aaa=std::fopen("load.txt",mode==OPEN_BINARY?"rb":"r");
	if(aaa==NULL)return 0;
	fgets(testtest,sizeof(testtest),aaa);
	fclose(aaa);
	return 1;
}

int TestClass::save(int mode) {
	if(mode!=OPEN_BINARY && mode!=OPEN_TEXT)return 0;
	//aaa=fopen("save.txt",mode==OPEN_BINARY?"wb":"w");//エラー
	//aaa=::fopen("save.txt",mode==OPEN_BINARY?"wb":"w");//エラー
	aaa=std::fopen("save.txt",mode==OPEN_BINARY?"wb":"w");//エラー
	if(aaa==NULL)return 0;
	fprintf(aaa,"%s",testtest);
	fclose(aaa);
	return 1;
}

int main(void) {
	TestClass test;
	test.load(TestClass::OPEN_TEXT);
	test.save(TestClass::OPEN_BINARY);
	return 0;
}

コード:

D:\(中略)\classtest.cpp: In member function `int TestClass::load(int)':
D:\(中略)\classtest.cpp:25: error: `fopen' is not a member of `std'
D:\(中略)\classtest.cpp: In member function `int TestClass::save(int)':
D:\(中略)\classtest.cpp:36: error: `fopen' is not a member of `std'

Re: C++でクラス内の関数と同名の標準関数の呼び出し

Posted: 2011年1月18日(火) 17:14
by YuO
みけCAT さんが書きました:stdを付けるとエラーが出ました。

コード:

#include <stdio.h>
C標準ライブラリ由来のC++の標準ライブラリは,先頭にcを付けて.hを取り除いた名前になります。
つまり,

コード:

#include <cstdio>
のように書けば,std::fopenが用意されます。
ただし,マクロ系は当然名前空間とは無関係に存在します。

Re: C++でクラス内の関数と同名の標準関数の呼び出し

Posted: 2011年1月18日(火) 17:23
by ゆーずぃ
gccに起因するトラップのようです。
こちらに少し詳しくありました。
http://unicus.jp/wp/archives/39

Re: C++でクラス内の関数と同名の標準関数の呼び出し

Posted: 2011年1月18日(火) 20:58
by みけCAT
YuOさん
うまくできました。
ありがとうございます。

コード:

//#include <stdio.h>
#include <cstdio>

class TestClass {
	private:
		FILE* aaa;
		char testtest[100];
	public:
		static const int OPEN_BINARY=1;
		static const int OPEN_TEXT=2;
		
		int fopen(const char* filename);
		int load(int mode);
		int save(int mode);
};

int TestClass::fopen(const char* filename) {
	//ダミー
	return 0;
}

int TestClass::load(int mode) {
	if(mode!=OPEN_BINARY && mode!=OPEN_TEXT)return 0;
	//aaa=fopen("load.txt",mode==OPEN_BINARY?"rb":"r");//エラー
	//aaa=::fopen("load.txt",mode==OPEN_BINARY?"rb":"r");
	aaa=std::fopen("load.txt",mode==OPEN_BINARY?"rb":"r");
	if(aaa==NULL)return 0;
	std::fgets(testtest,sizeof(testtest),aaa);
	std::fclose(aaa);
	return 1;
}

int TestClass::save(int mode) {
	if(mode!=OPEN_BINARY && mode!=OPEN_TEXT)return 0;
	//aaa=fopen("save.txt",mode==OPEN_BINARY?"wb":"w");//エラー
	//aaa=::fopen("save.txt",mode==OPEN_BINARY?"wb":"w");//エラー
	aaa=std::fopen("save.txt",mode==OPEN_BINARY?"wb":"w");//エラー
	if(aaa==NULL)return 0;
	std::fprintf(aaa,"%s",testtest);
	std::fclose(aaa);
	return 1;
}

int main(void) {
	TestClass test;
	test.load(TestClass::OPEN_TEXT);
	test.save(TestClass::OPEN_BINARY);
	return 0;
}