クラスのメンバ変数を外部から読み取りしたいです.
たくさん変数があるので,できればゲッターを作りたくありません.
内部からのみ読み書きが可能で,外部からは読み取り専用にしたいです.
この状態にできればprivateかpublicかは問いません.
友人にはあきらめろと言われましたがどうしても気になったので質問させていただきました.よろしくお願いします.
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答4件
0
五年も前にこんなの書きました。
これをちょっといぢると:
C++
1#include <functional> 2 3template<class T> 4class property { 5private: 6 std::function<T()> get; 7public: 8 property(const std::function<T()>& getter) : get(getter) {} 9 T operator()() const { return get(); } 10 operator T() const { return get(); } 11 typedef T value_type; 12}; 13 14#define GET_PROPERTY(X) X([this]() {return X##_; }) 15 16// おためし 17#include <iostream> 18#include <string> 19#include <chrono> 20#include <ctime> 21 22class person { 23private: 24 // プロパティ名に'_'を付けること。 25 std::string name_; 26 int age_; 27 28public: 29 person(const std::string& n, int a) : 30 name_(n), GET_PROPERTY(name), 31 age_(a), GET_PROPERTY(age), 32 // 引数を取らない関数ならなんでも♪ 33 now([]() -> std::string { 34 std::time_t t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); 35 return std::ctime(&t); }) {} 36 property<std::string> name; 37 property<int> age; 38 property<std::string> now; 39}; 40 41int main() { 42 using namespace std; 43 person adam("adam", 20); 44 int age = adam.age; // do this 45 cout << adam.name() << " is " // or this 46 << age << " years old at " 47 << adam.now() << endl; 48}
投稿2019/04/05 11:47
編集2019/04/06 02:29総合スコア16612
0
書きたくない、って言っても書くしかないのがC++です。
一回書いたら終わりなので根気よくgetterを作るのが得策です。
一応、defineで作る方法を書いてみましたが、
どっちかというとエディタの置換を使って機械的に生成したほうがトラブルは少ないでしょう。
#include <iostream> #include <vector> #define GETONLY(T, NAME) private: T NAME; public: const T& get_##NAME() const {return (NAME);} class X{ GETONLY(int, n); GETONLY(std::vector<int>, list); public: X():n(10),list(){} }; int main() { X x; std::cout << x.get_n() << std::endl; }
(出来合いのライブラリのように)クラスを書き換えることは出来ないがprivate領域の値が知りたい
デバッガのような使い方として値を見たい、という話なら、一応闇魔法はあるので紹介だけしておきます。
投稿2019/04/05 09:47
総合スコア2856
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
こんにちは。
私もマクロで量産に賛成です。参照はインラインで定義できるようです。(できないと思ってましたが、C++11でできるようになっているみたいです。)
しかし、残念オーバーヘッドが結構あるので、getter量産の方が良さそうです。
C++
1#include <iostream> 2 3#define READ_ONLYXX(dType, dName) private: dType dName##_; public: dType const& dName = dName##_; 4 5class Foo 6{ 7 READ_ONLYXX(int, bar); 8public: 9 Foo() : bar_(123) { } 10}; 11 12int main() 13{ 14 Foo foo; 15 std::cout << foo.bar << std::endl; 16 std::cout << sizeof(foo) << std::endl; 17// foo.bar = 456; 18}
【追記】
catsforepawさんのコメントで気がついたのですが、1つ見落としていました。
コピー・コンストラクタでコピーできてしますのですが、コピーされた方の参照は、コピー元のメンバ変数を参照します。かなり危険なのでこれはコピー禁止(コピー・コンストラクタをdeleteするなど)しない限り使わないほうが良いです。(参照メンバがあるとコピー代入演算子は自動生成されないです。)
投稿2019/04/05 09:05
編集2019/04/06 03:58総合スコア23274
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/04/06 01:06

0
たくさん変数があるので,できればゲッターを作りたくありません.
プリプロセッサマクロでgetterを量産する、というのも1つの選択肢かもしれません。
投稿2019/04/05 08:29
総合スコア146738
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。