7

Foo.hで:

class Foo
{
public:
    Foo();
    static const unsigned int FOOBAR = 10;
    static const unsigned int BARFOO = 20;

private:
    unsigned int m_FooBar;
    bool m_Bar;
    void Bar();
};

Foo.cpp:

Foo::Foo()
    : m_FooBar(FOOBAR), // this works
      m_Bar(false)
{
}

void Foo::Bar()
{
    //m_FooBar = m_Bar ? FOOBAR : BARFOO; // linker fails *1
    m_FooBar = FOOBAR; // ok
}

GCC 4.5.3 でコンパイルしています。行 *1 のコメントを外すとリンカーが失敗する理由はありますか?

Foo.o: In function 'Foo::Bar' (name unmangled):
Foo.cpp: undefined reference to `Foo::FOOBAR'
Foo.cpp: undefined reference to `Foo::BARFOO'

VC2005、2008、2010、CB2010で試しました。それらはすべて正常にコンパイルおよびリンクされました。この場合、GCC が失敗するのはなぜですか?

here の答えを考えると、他の一般的なコンパイラが GCC のように失敗しないのはなぜですか? いずれにせよ、GCC やその他の一般的なコンパイラのバグに違いありません。それとももっと合理的な説明がありますか?

4

2 に答える 2

4

正式には、ヘッダーは静的定数のみを宣言し、それらも定義する必要があります(少なくともC ++ 03では)。ただし、それらの値のみを使用する場合は、ほとんどの場合、これを回避できます。

C ++ 11では、これは、静的が「odr-used」の場合に定義が必要であるとより正式に指定されています。この*1行はその一例です。トライアド演算子は値への参照を形成しようとしますが、コンパイラ(または実際にはリンカ)はそれができないことを認識します。


C++11規格によると

9.4.2静的データメンバー
§3...
メンバーがプログラムでodr-used(3.2)であり、名前空間スコープ定義に初期化子が含まれていない場合でも、メンバーは名前空間スコープで定義されるものとします。

于 2012-09-19T06:43:59.507 に答える
0

これらのメンバーを定義してみてください。

static const unsigned int FOOBAR = 10;
static const unsigned int BARFOO = 20;

クラス宣言の外。

Foo::FOOBAR = 10;
Foo::BARFOO = 20;
于 2012-09-19T06:43:39.833 に答える