2012-04-26 15 views
2

私はいつも、そのクラスでしか変更できないゲッターを使わずにクラスメンバーを作る方法があるのだろうか?クラス以外の誰のためにも定数はありますか?

私が考えているのは、このようなものです。

class A 
{ 
    public: 
     crazyconst int x; 

     void doStuff() 
     { 
      // Gettin' stuff done 
      x = someValue; // OK 
     } 
}; 

int main(int argc, char** argv) 
{ 
    A a; 
    a.x = 4; // ERROR 
} 

これは表示されますが、そのクラスの横にあるすべてのユーザーには読み取り専用です。

+1

'main'の' y = a.x' intが合法であるべきことを意味しますか?そうであれば、そう言いましょう。そうでなければ、「プライベート」を使用するなど、多くの答えが得られるからです。 – vsz

+0

私はいくつかの奇妙な言語は、C/C++ではなく、そのようなことをしていると思います。 –

+0

はpublic int xMethod(){return x;}を持ち、xはプライベートメンバーです。 – Dhananjay

答えて

4

答えは、あなたは何らかのゲッターなしでこれを行うことはできません。しかし、ゲッターを再利用できるようにすることができ、括弧なしでフィールドワークの簡単な構文(ほとんど)を作ることができます。

(C++ 11必須)

template<typename Friend, typename FieldType> 
class crazyconst 
{ 
    FieldType value; 
    friend Friend; 
    FieldType& operator=(const FieldType& newValue) { return value = newValue; } 
public: 
    operator FieldType(void) const { return value; } 
    FieldType operator()(void) const { return value; } 
}; 

class A 
{ 
public: 
    crazyconst<A, int> x; 

    void doStuff() 
    { 
     // Gettin' stuff done 
     x = 5; // OK 
    } 
}; 

int main(int argc, char** argv) 
{ 
    A a; 
    int b = a.x; 
    int c = a.x(); // also works 
} 

C++ 03バージョン:http://ideone.com/8T1Po

しかし、注意してくださいが、これはコンパイルが、期待通りに動作しません。

const int& the_x = a.x; 
a.doStuff(); 
std::cout << the_x; 

OTOH、これはうまくいくはずです:

const auto& ref_x = a.x; 
a.doStuff(); 
std::cout << ref_x; 
+0

このソリューションをC++ 11に正確に限定するものは何ですか?ありがとう! – guga

+1

@guga:http://stackoverflow.com/a/702701/103167 –

6

あなたのクラスには、constという非公開の非データ項目への参照が含まれている可能性があります。

編集:しかし、これを行うと、コンパイラ生成のコピーコンストラクタとコピー代入演算子を使用できなくなることを指摘しておきます。

+1

'const_cast'が心配されていない方には良いアプローチです。 –

+0

@BenVoigt:この特定のケースで 'const_cast'を心配するのはなぜですか? –

+0

@Als、main: 'const_cast (a.x)= 4;' – chris

関連する問題