他の名前空間のクラスをpublicに継承した時、その基本クラスのpublicかprotectedの
メンバにアクセスする時、名前空間の指定は必要なのでしょうか?
例えば
#include <iostream>
namespace CLASS_A {
class A {
public:
void f() { std::cout << A::f() << std::endl; }
};
} // namespace CLASS_A
namespace CLASS_B {
class B : public CLASS_A::A {
public:
void Func() { CLASS_A::A::f(); } // ここが問題
};
} // namespace CLASS_B
int main()
{
CLASS_A::A *p = new CLASS_B::B;
p->f();
delete p;
return 0;
}
上のコード、VC++6だとエラーで、BCCだと問題ないです。
そして問題の void Func() { A::f(); } とするとVC++はOKでBCCだとエラーです。
どうもVC++のバグっぽいのですが、実際はどうなのでしょう?
あとVC++7ではどうなのかも知りたいです。
お願いします。
VC++7.1 では A::f() でも CLASS_A::A::f() でもおっけーです。
gcc3.1でも同様の結果となりました。
> void Func() { CLASS_A::A::f(); }
標準C++の規格上は,これが正しいはずです.
CLASS_A::をいちいち書くのが煩わしい場合は,次の如くすることもできます.
namespace CLASS_B {
using CLASS_A::A;
class B : public A {
public:
void Func() { A::f(); }
};
} // namespace CLASS_B
おふたりとも、ありがとうございます。
> 標準C++の規格上は,これが正しいはずです.
との事ですが、VC++6ではエラーなので A::f() の形でいきます。
これが規約的にOKかは知りませんがVC++7でもGCCでもOKとの事なので気にしない事にします。
解決忘れました.
実験:こんな場合は何が起こるかな?
#include <iostream>
namespace CLASS_A
{
class A
{
public:
virtual void f(){ std::cout << CLASS_A::A::f << std::endl; }
};
}
namespace CLASS_B
{
class A
{
public:
static void f(){ std::cout << CLASS_B::A::f << std::endl; }
};
class B : public CLASS_A::A
{
public:
void f(){ A::f(); }
};
}
int main()
{
CLASS_B::B obj;
obj.f();
}
ワタシの環境での結果
VC++.NET2002 CLASS_A::A::f
BCC5.5 CLASS_B::A::f
VC7.1, gcc3.1 では CLASS_A::A::f でした。
base-classが優先されるのかしら。 > VC/gcc
επιστημηさん
実験におつきあいいただき,ありがとうございます.
ワタシの理解では,言語の規格上はBCC5.5の結果が正しいと思うのですが,いかがなも
んでしょ?
ちなみにVC++6でもCLASS_A::A::fでした。
実際にこういうコードを書くことはまず無いと思うので大した問題では無いかと。
規約上でどちらが正しいのかはちょっと気になりますが。
・・・コンパイラいじめ(笑)?
> 言語の規格上はBCC5.5の結果が正しいと思うのですが,いかがなもんでしょ?
どうでしょね。基底クラスを先に見に行ってもよさげにも思います。
cppllの猛者連中に訊いてみましょかね。
> cppllの猛者連中に訊いてみましょかね。
ワタシも規格書を見てみますが,有識者の見解をお聞かせいただければ尚幸いです.
お手数ですが,よろしくお願いします.