[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 2chのread.cgiへ]
Update time : 07/16 11:48 / Filesize : 200 KB / Number-of Response : 824
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

C++相談室 part61



1 名前:デフォルトの名無しさん mailto:sage [2008/03/09(日) 19:37:43 ]
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。

139 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 12:50:07 ]
実行時に要素のバイト数は、どこにも格納されてない。
と、考えて良い。

コンパイルする時点では、当然型が分かるので、それを使う。
この段階というか、かなり基礎。

※RTTIは上記が理解出来た上で。

140 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 12:59:28 ]
>>138
いっぺん、自作クラスにoperator newとoperator deleteを実装してみればいいんじゃないかな。

乱暴な説明だけど、C++には「確保/削除するバイト数を受け取る、new/delete一族の大ボス的存在」である
::operator new(size_t)と::operator delete(void*, size_t)があって(他にも多重定義があるけど、とりあえず今はこの2例)、
たとえば int* p = new int; なんてのは、int* p = ::operator new(sizeof(int)); みたいにコンパイル時に解釈される。
同じく、後にdelete p; が出てきたら、pがint型のポインタなのはコンパイラにはわかるから(てか俺等にだってわかる)、
こっちは ::operator delete(p, sizeof(int)); になる。

141 名前:デフォルトの名無しさん [2008/03/21(金) 13:24:09 ]
>>138

>int* p = new int; なんてのは、int* p = ::operator new(sizeof(int));

int *p= new int [100]; は int *p=::operator new(sizeof(int)*100);
みたいになるんでしょうけど、要素のサイズが2バイトなのか4バイト
なのかの情報をコンパイル時にポインタに付加しておかないと、p[i]の
アクセスがうまくいかないのではないかと思うのですが、どうでしょうか?



142 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 13:25:59 ]
>>141
p[i]のpの型はコンパイル時に分かってるんだから

143 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 13:44:43 ]
まあ、強いて言えば、生成されたコード内に埋め込まれているって感じなのかな。

delete[] p;するときに、各要素のデストラクタを起動しなければならないわけだけど、
要素数は p = new T[count]; のcountで、実行時に変わる可能性のあるものだから、
ポインタの前かなんかに隠しておかなければならないわけ。
ちなみに、メモリブロックを単純に解放するだけなら要素数を隠しておく必要はないよ。
free()にサイズを指定しないでしょ?
メモリマネージャはメモリブロックの総バイト数をどこかに隠しておくかもしれないけど、それは別の話。

あとは、
T *p;
for(size_t i = 0; i < count; i++){
p->destruct();
++p; //←これ
}

これの++pがどうコンパイルされるかという、>>139が言うようにC言語レベルの基本的な話。


144 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 13:56:21 ]
>>141
> p[i]のアクセス
たとえばintが4byteの環境だとすると、p[i] と書かれた箇所はネイティブコードにおいては
「pのアドレス+i*4byteのメモリアドレスへ行ってそこから先4byte分に書き込まれているビット配列を〜」
という風に、既にintが「4byte」というミもフタも無い表現に変わっているから、型情報も何も関係無いよ。

145 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 14:27:51 ]
>>141
p[i]というコードはコンパイルすると、アドレスはp+4*iといった意味の命令が生成される。
4が出てくる理由はpの宣言int* pによるもの(intが4byteの環境の場合)。

146 名前:145 mailto:sage [2008/03/21(金) 14:36:28 ]
すまん、144と同じ事書いてしまった。

147 名前:141 [2008/03/21(金) 17:03:54 ]
返事が遅くなってすみません。みなさん、ありがとうございます。

>>144 さんと >>145 さんの説明で

4byteという要素バイト数の情報をポインタp自体が保持して
いるのではなく、p[i]にアクセスする際にコンパイラがp+4*i
を計算する命令を生成しているだけ、ということがやっと理解
できました。



148 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 18:35:45 ]
配列 new の場合、アップキャストは行わないから
配列のサイズは型から静的に決まる、と。
というか、アップキャストはできない。
そこが鍵だな。

149 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 18:36:13 ]
×配列のサイズ
○要素のサイズ

150 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 18:44:36 ]
C++ 的にはフォーマットの決まった string の中から数字を
読み出したりするにはどうするのがお薦めなのでしょうか?
例えば

string s("# foo 30 bar 0.1 xlajkdfl;ajkds");

から 30, 0.1 を抜く場合。

int n;
double x;
sscanf(s.c_str(),"# foo %d bar %lf",&n,&x);

としたりするのですが、もっと「本来」の方法はあるのでしょうか?
どうも workaround 的な気がするので。



151 名前:デフォルトの名無しさん [2008/03/21(金) 18:48:30 ]
atofで一つずつ進めて数値になる所を取り出す

152 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 18:51:36 ]
それはないな

153 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 19:53:08 ]
自分で字句解析器を書く。

154 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 20:00:28 ]
各種正規表現ライブラリの後方参照を使う

155 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 20:29:16 ]
>>150
そういうのが必要になる状況ってあまり無くない?

156 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 21:08:24 ]
>>155
俺はソースコード解析したい時によくでる。
字句解析ライブラリもってこいって話だよな・・・

157 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 21:51:06 ]
字句解析なら分かるんだけど、>>150は何か違う気がしたんで・・・
そうなら、分割の話から入るだろうし。

もしかして自然言語文からの抽出とかかな?



158 名前:150 mailto:sage [2008/03/21(金) 23:35:25 ]
皆様どうもありがとうございました。私は結構こういう必要に出会います。
主にデータファイルをフォーマットし直したり、それを処理する場合です。
例えばデータフォーマットの情報などた先頭にあったりして、その情報を
元に解析したりする場合です。無視して決め打ちする事も可能な場合も多い
ですが、安全性のために整合性をチェックしています。

>>154 さんの方法が私には合っていると思います。普段 Ruby とかも使って
いて正規表現も使っているのに惰性で C 的にを使い続けてる自分の頭の堅さ
には呆れました。基本的に以下のようなコードで対応することを考えています。

まだあまり考えていないのでもう少しエレガントに書けるだろうとは思います。

string s("# foo 30 bar 0.1 xlajkdfl;ajkds");
boost::regex r0("^# foo ([0-9.]+) bar ([0-9.]+).+");
boost::match_results<std::string::const_iterator> mr;
if(boost::regex_match(s,mr,r0)){
const int n = boost::lexical_cast<int>(mr.str(1));
const double x = boost::lexical_cast<double>(mr.str(2));
cout << n<<"\t"<<x<<endl;
}



159 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 00:19:27 ]
>主にデータファイルをフォーマットし直したり
それまさに字句解析の範疇な気がするけど・・・w

まぁ正規表現で簡単に済めばそれで良いと思うけどね。

160 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 12:44:30 ]
>>159
> まぁ正規表現で簡単に済めばそれで良いと思うけどね。

regex ってかなり強力だと思う。テキストから情報拾う場合
に regex では簡単に通用しない場合ってどういうケース?

161 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 13:14:39 ]
>>160
ネストした括弧の対応を取るとか

162 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 14:07:16 ]
そこでboost::xpressiveですよ

163 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 14:15:50 ]
boost もいろいろあってわからんなぁ。xpressive だと簡単なのかな。

俺だと char ごと読み取って '(' ')' を +1, -1 でカウントするとか
低レベルな事を考えちゃうけど。

164 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 14:52:00 ]
 通常の正規表現では任意のネストを表現することができない。
→xpressive ではパターンの自己再帰記述が可能。
→正規表現の枠を超える表現力を持つ(文脈自由文法)。
→xpressive だとネストの対応が可能。

165 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 15:01:28 ]
boostの文字列処理ライブラリの事ならboost本のサンプルで読めたな

166 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 15:21:10 ]
boost 本でお薦めってある? 本あまり出てないよね。

Karlsson の本は目を通したけど感じは判ってよいけど便利な本
という感じではない。秀和から出てる稲葉さんは本厚いし内容あるのかな。


167 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 17:31:22 ]
inabaさんのは導入+軽いリファレンスにはいいかも
おおまかな概念と使用例が載ってる
boostもう使ってるよ〜という人にはあまり必要ないかも




168 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 17:31:23 ]
複数の派生クラスがそれぞれ値の異なるconst staticなメンバ変数をもっていて、
基底クラスへのポインタを使って読み取りたいのですが、どうすればいいでしょう
基底クラスへのポインタの配列に、いろいろな派生クラスを突っ込んでいる状態なので、
直接アクセスすることは出来ません


169 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 17:49:42 ]
ttp://www.s-cradle.com/developer/sophiaframework/tutorial/Cpp/virtual.html

170 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 17:54:12 ]
>>166
C++ Template Metaprogramming

171 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 17:56:20 ]
>>168
普通に仮想関数で
struct Base { virtual StaticMemberType GetStaticMember()=0; };
struct DerivedA : public Base {
StaticMemberType GetStaticMember { return DerivedA::staticMemember; }
};
あるいはRTTI使ってマルチメソッド。

172 名前:171 mailto:sage [2008/03/22(土) 17:59:13 ]
ごめん引数1つのマルチメソッドはないなw

173 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 18:22:26 ]
あー、関数をアクセサにすればよかったですね。何やってんだ俺
ありがとうございました

174 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 21:56:34 ]
>>170
どうもありがとうございます。実はその本は持っていて次に読む予定。
しかし、これも洞察には優れているとは思うけど、便利な本では
ないかも。面白そうなんで期待してるけど。

175 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 22:03:15 ]
>>174
面白くないよ。mplの単なるリファレンス。

176 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 00:53:31 ]
DLLを読み込み、一部の機能のみを使った場合、
メモリの消費量はまるまるDLL分増えるのでしょうか
それとも使った機能の分だけ増えるのでしょうか

177 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 01:03:35 ]
環境依存の話はスレチだけど、まるまる増えると思うよ。



178 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 01:12:30 ]
仮想メモリはまるまる
物理メモリはコードについては使った分
データはシラネ

179 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 01:30:13 ]
ありがとうございました
使いたいライブラリが8MBくらいあるもので、
まるまる増えるのはちょっとアレかな、と思って質問しました
改変可なので、必要な部分だけ取り出そうと思います

180 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 03:06:24 ]
Managerクラスがあり
その機能は、一部のクラス(と言っても10個ぐらいある><)
にしか利用できないって設計の場合
一部のクラスをfriendする以外に何か方法はありませんか?


181 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 03:13:01 ]
その一部のクラス以外はmanagerクラスのインスタンスを手に入れられないようにする。

182 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 09:41:11 ]
>>180
freind じゃダメな理由を書いた方が答えが得られやすいと思う。

183 名前:>>182 mailto:sage [2008/03/23(日) 09:42:51 ]
ミスった... orz

freind ⇒ friend

184 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 09:45:07 ]
friend先に依存が出来るからじゃね?
普通、friendは最終手段だし

185 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 12:07:26 ]
そんなことはない。

186 名前:>>182 mailto:sage [2008/03/23(日) 13:05:05 ]
friend 先に依存って何?

187 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 13:58:48 ]
一部のクラスだけ特別扱いするというのがManagerクラスの仕様なら、
friendによる依存は妥当だと思う。



188 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 14:45:51 ]
一部のクラスの基底クラスとして
Manager を取得するクラスを作って、
その1つだけを friend にすれば?

189 名前:180 mailto:sage [2008/03/23(日) 14:58:22 ]
friendが結構な数になってしまうんです。
下手すれば私のリアルfriendより多いぐらい
それが悔しくて

190 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 14:59:16 ]
誰が上手い事を言えと

191 名前:184 mailto:sage [2008/03/23(日) 15:01:24 ]
俺は181に一票で

192 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 15:02:43 ]
その方法を聞いてるんだろw

193 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 15:09:28 ]
パスワード掛ければいいんじゃないですかね

194 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 15:14:48 ]


195 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 15:25:03 ]
権限プログラミングってのも面白そうじゃないか

196 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 15:42:23 ]
singletonなら簡単なのにな

197 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 16:01:39 ]
思い出したw

____
|← reject|  boostの中の人  singleton   ユーザー
. ̄.|| ̄ ̄        ┗(^o^ )┳(`Д´)┳(^o^ )┛≡=-
  ||            ┏┗   ┗┗  ┏┗ ≡=-
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄



198 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 16:06:07 ]
ユーザーは欲してると思うが

199 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 16:34:52 ]
にわかに得た知識で面白いこと考えた!
Managerのインスタンスを受け取る関数の引数に関数オブジェクトを使って
内部で一定のアルゴリズムで正しい値を返すもの(パスワードの暗号化みたいな)にのみそのインスタンスを渡してやる風にすればいいんじゃね?
更にインスタンスを受け取る関数をテンプレート化してやり、欲しい権限までのクラス型インスタンスを返すようにしてやればアクセス制限も出来て完璧!


とここまで考えてわざわざこんなことしてもオーバーヘッドが大きいだけなことに気づいた
そもそも何の意味があるんだっけか

200 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 16:45:12 ]
だから >>188 でいいだろ、別に。

201 名前:デフォルトの名無しさん [2008/03/23(日) 16:57:35 ]
Managerクラスコンストラクタなどをprotectedにして、使うクラスはManagerを継承する。


202 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 17:02:41 ]
>>188 >>199 >>201
これらの方法は、Managerクラスの許可なく好き勝手に権限のあるクラスを作れる。
そういうのを>>180は制限したいんじゃないの?

203 名前:>>182 mailto:sage [2008/03/23(日) 17:08:28 ]
>>201
そう言うのは最悪。

あとから見て、継承が本当に必要だったのか、単に特定のメソッドを
使わせるために継承しているのかがわからなくなるから。

204 名前:201 [2008/03/23(日) 17:21:39 ]
>>203
意味がよく分からないけど、、、「特定にメソッドを使わせるために継承が必要かどうかがわからなくなる」ってこと?
そんなこと言ってたら何もできない。
friendだったら、なぜfriendにしたか分からなくならないの?

friend よりいいと思うけどな。
friend じゃprivateのメンバにアクセスできてしまう。

Managerクラスを機能を利用するんだから、継承しかないでしょ。
使う側のクラスに持たせるとなると、コンストラクタとかはpublicになってしまうし。

205 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 17:40:32 ]
継承すると
Managerの中のstaticでない変数とか勝手に作られない?


206 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 17:41:03 ]
>>203
Manager クラスじゃなくて単に許可コントロール用の class を作る
というのは有りじゃない?そういう例をまともな本で見た記憶がある。

207 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 17:42:27 ]
-カーズは-
2度と地球へは戻れなかった…。
鉱物と生物の中間の生命体となり
永遠に宇宙空間をさまようのだ。

そして死にたいと思っても死ねないので
―そのうちカーズは考えるのをやめた。

全部globalにすればいいじゃん



208 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 17:44:01 ]
>>206
電波の缶詰の人のサンプルもそうだった

ライブラリ的なものを
外部からいじられないようにするためだったら
そんな感じでもいいんじゃまいか

村八分

209 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 17:47:19 ]
Managerインスタンスを受け取るために、Managerにコールバックしてもらえばいいんじゃない?
class FriendClassA; // 前方宣言
class FriendClassB;
class Manager
{
public:
  class Friend { public: virtual void authorize(Manager* m) = 0; };
  void getInstance(Friend* p)
  {
    if( dynamic_cast<FriendClassA*>(p) ||
        dynamic_cast<FriendClassB*>(p) ||
        /* 権限のあるクラスかをチェック */ )
    {
      p->authorize(this);
    }
  }
};

210 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:25:34 ]
それは、インスタンス取るのに時間かかるし
friendでいいじゃんって話になるも

211 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:40:51 ]
速度が重要ならtemplate部分特殊化とかで。

class Manager
{
public:
template <class Unauthorized>
static void authorizedProc(unauthorizedClass * p)
{ std::cout << "not authorized" << std::endl; }
template <>
static void authorizedProc(authorizedClassA * p)
{ p->Proc(m_instance); }
// 以下許可するクラス分同じコード
private:
Manager m_instance;
};

冗長だし検証してないけど。

212 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:45:30 ]
Manager を使えるクラスを作成する場合には
ファクトリクラスを通すようにする。
で、そのファクトリクラスを friend にして、
そこで Manager クラスを取得して、
各クラスにそれを渡すようにする。
設定関数は各クラスの共通基底クラスに作って、
それをファクトリクラスの friend にする。

213 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:46:54 ]
先輩から聞いたのですが、extern "C" {}せずに構造体を宣言すると、
余計なクラス情報がくっつくって本当ですか?

214 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:52:41 ]
そんなことは聞いた事が無いが、
特定のコンパイラでそういう事があるとかいうんだったら俺は知らない。

215 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:55:11 ]
クラス情報って具体的には何なんだ?

216 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:57:34 ]
>>213
マングリング名にクラス情報がくっつくって話だと思う。

217 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:59:55 ]
>>214-216
言ってたのはシリコンバレー帰りの先輩です
純粋なCの構造体にするにはやはりextern "C"が必要なのですね。
ありがとうございました。



218 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 19:00:36 ]
>>217
どこからそういう判断をしたんだ?w

219 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 19:01:52 ]
構造体にextern "C"は関係無いだろ

220 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 19:02:10 ]
>>216
構造体名って C でそもそも何らかのマングリングされるの?

221 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 19:07:59 ]
C++なら名前空間やらなんやらくっつくだろ。

222 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 19:10:41 ]
C で付かないなら
純粋な C の構造体かどうかなんて
どう区別するんだろうか。

223 名前:>>182 mailto:sage [2008/03/23(日) 19:46:38 ]
>>204
まじめな話、もう一度継承についてちゃんと勉強した方がいいと思う。
(>>205 の内容を理解できてる?)

継承はアクセス制限のためにあるものじゃない。
極端な話、全てが public であったとしても、継承は有用。

これに対して、friend は純粋にアクセス制限を回避するもので、かつ
アクセス制限を回避する以外の機能は無いから、なぜ friend にしたか
がわからなくなることはない。
(もちろん、なせアクセス制限を回避する必要があるかはどっかに書いて
おく必要があるだろうけど。)

>>206
それならアリだと思う。

224 名前:201 [2008/03/23(日) 19:54:02 ]
>>223
>>205
作られるけど。外から参照されたくないものはpublicにしなけらばいいじゃん

225 名前:201 [2008/03/23(日) 20:00:37 ]
>>223
>継承はアクセス制限のためにあるものじゃない。
>極端な話、全てが public であったとしても、継承は有用。

だから、継承が駄目なんですか?
継承は色んな意味で使えて「わかりにくい」から駄目ってこと?


226 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 20:00:37 ]
何かもう駄目だなここって思ったの俺だけだろうか

227 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 20:02:29 ]
Manager 使ってる部分を別プロジェクトにする。
あとは各クラスのオブジェクト生成を外部から隠せばいい。



228 名前:>>182 mailto:sage [2008/03/23(日) 21:01:54 ]
>>224
> 作られるけど。外から参照されたくないものはpublicにしなけらばいいじゃん

おいおい、ほんとにもう少し勉強してからこいよ。
引っ込みつかなくなってるだけならいいけど、マジでそう思ってるとしたら
ちょっとまずいよ。

まずい理由の一つは、private でもその変数が見えなくなるわけじゃない、
アクセスできなくなるだけだから。

この違いわかってる?

>>225
> 継承は色んな意味で使えて「わかりにくい」から駄目ってこと?

>>203 に書いたのはそう言うこと。

それしか方法が無いならしょうがないけど、friend と言うもっといい方法があ
るのにわざわざ使わないのは、別の意図があるようにとられる危険性が高い。

229 名前:201 [2008/03/23(日) 21:17:23 ]
>>228
>マジでそう思ってるとしたらちょっとまずいよ。

Managerを継承していないクラスから参照されたくない場合はpublicにすれば良いって事だよ?

>まずい理由の一つは、private でもその変数が見えなくなるわけじゃない、
>アクセスできなくなるだけだから。

「見える」→メンバ変数の値が取得できる。(getter)
「アクセス」→メンバ変数の値が書きかえれる。(setter)
って意味で言ってるのなら
getter、setter定義してやれば、当然見えるしアクセスも可能。



230 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 21:42:53 ]
もしかして201氏は、
Managerは1つのクライアント(Managerを使うクラスオブジェクト)の管理のみ引き受けるもので、
クライアントと同数のManagerオブジェクトが必要と考えているのではないだろうか。

231 名前:>>182 mailto:sage [2008/03/23(日) 22:07:14 ]
>>229
> 「見える」→メンバ変数の値が取得できる。(getter)
> 「アクセス」→メンバ変数の値が書きかえれる。(setter)

ほら、全然理解できてない。

簡単な例でいうと、

int a, b;

class X {
private: int a;
};

class Y: public X {
 int foo(){ return a; }
 int bar(){ return b; }
};

ってやると、foo() の中で X::a をアクセスしようとするからエラーになるよね。

もし、C++ の private が変数を「見えなくする」なら bar() の b と同じように、
foo() は ::a を返すはずだろ?

これが、「見えなくなること」と「アクセスできなくなること」の違いなわけ。

これによる、影響は自分で調べてみてね。

>>230
まあ、それはそれでそれこそもっとよく考えろとしか言えないわけだが...

232 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 22:11:42 ]
何でこんな残念なスレになってしまったんだ。

233 名前:デフォルトの名無しさん [2008/03/23(日) 22:12:43 ]
だって にちゃん だもの

234 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 22:56:01 ]
VSyncの話したらひどいことになりそう

235 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 22:57:56 ]
>>231
初心者スレでやれ
ウザイ

236 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 23:03:27 ]
結局>>182って文句言ってるだけで答えて無いじゃん

237 名前:>>182 mailto:sage [2008/03/23(日) 23:14:58 ]
答えは >>188 で既にでてるだろ。

まあ、10個ぐらいなら全部 friend 宣言してもいいと思うけど。

もしかして君も >>201 みたいに理解できてないやつなの? (w



238 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 23:32:29 ]
>>188だとManager::getInstanceみたいなので取得するのと大差無いと思うが・・・

まぁ、それはともかく、>>180にfriendなどを使ってまで
制限する必要性があるのか、疑問だな。
クラスごと使わせなくするとこにfriendを使用している時点でおかしいと思う。

無名名前空間やdetails名前空間で十分なんじゃないか?


239 名前:201 [2008/03/23(日) 23:44:18 ]
>>231
>foo() の中で X::a をアクセスしようとするからエラーになるよね。

アクセッサをManagerの方に定義することを考えていたんだけどな。
「見える」「見えない」の話じゃんくてprivateだからだろ。

>もし、C++ の private が変数を「見えなくする」なら bar() の b と同じように、
foo() は ::a を返すはずだろ?

グローバル変数よりメンバ変数を参照しにいくのは知ってます。

Managerの方に「一部のクラス」に使わせたい機能だけ、protected または public にして
一部のクラスがManagerを継承すればいい。

Manager のprivateのメンバには「一部のクラス」も参照できない。

「一部のクラス」以外にManagerクラスのインスタンスを作られるのが困る場合は
コンストラクタなどをprotectedにすればいいんでは?


「一部のクラス」に対してManagerは一つらしいので、また違ってきますが・・・・






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<200KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef