基礎プログラミング講座第8回「ビットマスク」 (216)

みなさんこんばんは。
第8回プログラミング講座ではビットマスクをやっていきます。

orとandがわかればok以上

ビットマスクとはなんでしょうか?
まずはイメージから入ります。

ポイント教えろや

組み込み以外であんま使わなくね?

第1回からもういっかい

ロビンマスクの仲間?

前スレのリンクくらい張れや

皆さん、マスキングテープをご存知ですか?
塗装などで特定箇所を塗りたいときに塗る箇所以外に貼ってそこに色がつくのを防ぐテープですね。

ビットマスクもこれと同様のことを行っています。
ビットマスキングテープとでも呼べるようなものを用意し、それを対象のビットの集まりに貼ってあげます。
こうすることで特定のビットに操作を行うことができます。

例えば以下のような4ビットのビット列があるとします。

1101

このビット列は左から順番に
「脱衣所の電気」
「台所の電気」
「トイレの電気」
「リビングの電気」
の状態を保持しているとしましょう。
(当然ながら1が「オン」、0が「オフ」です)

台所の電気が付いているか調べたい場合はどうすればいいでしょうか?
ここで「マスク」を使います。

ここで登場するマスキングテープは

0100

です
AND論理演算はご存知ですね。
今回は「1101」にマスキングテープ「0100」をANDでマスクしてみます
するとどうでしょうか?
1101
0100 (AND)
0100 (答え)

ノイズ「あ?なんか文句あんのか!?」

パリティ「ふえぇ……」

わかりやすいな一階方見たかった

これはできる>>1 スレタイでググったが他の7回が見つからない あるんなら晒してくれ

台所の状態が「1」であることが取り出せました。

どうようにトイレの状態も調べましょう
トイレのマスキングテープは「0010」です

1101
0010 (AND)
0000 (答え)

トイレの状態は「0」つまり電気はついていないということですね。

もうお気づきですね。
「あるビットの状態を調べたいとき」はそのビットを「1」、他のビットを「0」のビット列を用意し、ANDでマスクしてやればいい訳です。

これを使えば何ができるのか。実践してみましょう。

せんせー逆についてないことを検出したい場合はどうnotてんの?

マスキングテープは読み取りではなく書き込みに使うものだよ

あるアンケートがあるとします。
アンケートの内容は以下のとおりです

Q1. あなたの性別は?(男:0、女:1)
Q2. あなたは肥満ですか?(いいえ:0、はい:1)
Q3. あなたは幸せですか?(いいえ:0、はい:1)
Q4. 彼女/彼氏はいますか?(いいえ:0、はい:1)

いつの時代のテクニックだよ

>>18
「特定のビットの状態を調べる」わけですか同じようにマスクしてやって
結果が1なら、そのビットは1、0ならそのビットは0とわかるわけです。
トイレの例を見てください。

vipで建てると毎度変なのが湧くな

>>21
きそのきそでしょう

アンケートの回答をビット列に整形してみます。
第1ビットがQ1、第2ビットがQ2、…のようになっています。

ここでマスクするためのビット列に名前をつけてやります。

SEX 1000
OBESITY 0100
HAPPINESS 0010
PARTER 0001

と定義します。

オブジェクト志向のいろはを簡潔に教えてもらいたいんだが

アンケートの結果 result ビット列にたいして、以下のように書くと結果が取り出せます。(C言語の場合)

&は先程の論理演算ANDをしめしています.

if (result & SEX) {
//女の場合
} else {
//男の場合
}

if (result & OBESITY) {
//肥満の場合
}

if (result & HAPPINESS) {
//幸せの場合
}

if (result & PARTNER) {
//彼氏、彼女がいる場合
}

さらに応用してみます。

if (result & (HAPPINESS | PARTNER))
{
}

これはどのような場合でしょうか?
| は論理演算ORを表しています

IPのサブネットマスクと思ったら違った

幸せな場合、彼氏がいる場合、両方の場合か

0以外ならTrueってのはこういう時便利そうだけど
C言語以外でもそうなってるの?

間違えました

if ((result & HAPPINESS) && (result & PARTNER))
{
}

こうでした

javaだとtrueかfalseのどちらかしかとれない変数型があってそれで条件分岐することになってる

(bit-and 2r0110 2r1100) ;4
(bit-or 2r0110 2r1100) ;14
(bit-xor 2r0110 2r1100) ;10

これは「幸せ」かつ「パートナー」がいる場合ですね。
これを調べれば「パートナーがいることと幸せなことの関連性」を調べることもできますね。

if ((result & OBESITY) && (result & PARTNER))
{
}

これだと肥満とパートナーの有無の関連性を調べることもできます。

>>33
俺らがいない!!!

俺ならここにelseっ!

perlもC同様0以外真だな
rubyは0もそれ以外も真
シェルスクリプトは0が真でそれ以外偽

では実際のプログラミングではどのように使えるのでしょうか?

ある画面に何かオブジェクトが4つ描画されているとします。

メニュー、キャラクターのHP、装備してる武器、装備してる防具

みたいなものだとします。
これを選択的に消したいとしましょう。
1つずつ消す場合、メニューと武器を消したい場合はどうでしょう

delete_menu()
delete_weapon()

のように2つ関数を実行する必要があります。

俺ら
if(result==0000)
{
}

>>36
これって且つってこと?
肥満かつ恋人がいるかってこと?

JAVAから入ったからCにbooleanなくて困った
booleanって一般的には珍しい型なの?

pythonも0以外真

誰かオブジェクト指向を伝授してくださいなんでもしますから!

>>43
C99にはbool型あるで

ビットマスクを使いましょう。

MENU 1000
HP 0100
WEAPON 0010
ARMOR 0001

そして消去関数 delete を用意します。
ビットマスクを使うと消したい対象のビットを組み合わせたビット列をdeleteに送るだけでよくなります。
ユーザー側はビット列を意識する必要はありません。

どういうことでしょうか

>>45
本読んで簡単なプログラム100個作れ

>>43
そうでもないと思うが
booleanのあるほうがプログラムの意図がはっきりするし近代的な言語だと思う

>>45
java書いてんだろ?
適当にしてたらそれがオブジェクト指向だ

delete関数の中身は以下のようになっています

void delete(bitfield bits)
{
if (bit & MENU) {
//メニュー消去
}

if (bit & HP) {
//HP消去
}

if (bit & WEAPON) {
//武器消去
}

if (bit & ARMOR) {
//防具消去
}
}

Cだとstdbool.hにboolが含まれてるっぽいな
C++だと標準

まーたIT速報の奴が自演しながらやってんのか
いい加減、作業場としてココを使うなよ
アフィ嫌いなVIPPERの連中が怒っても知らんぞ

この関数を使うユーザーがどのように引数を指定してやればいいんでしょうか?
簡単です。消したい対象を OR で渡してやるだけです。

HPと武器が消したいなら

delete(HP | WEAPON);

です。
では解説していきます。

基礎からってこっからやんのか

>>53

転載禁止
転載禁止
このすれ転載禁止

javascriptは0も空文字もundefinedもNaNもnullも偽扱いというクソキモい言語

>>48
まぁ実践あるのみだよな 文法書は読みまくっから基礎は押さえてるつもり

>>50
Cから入ったからいまいちオブ指のコツや感覚がわからんのよ

スレチすまん

懐かしきプログラミング

デリゲートの人?

HP | WEAPON

これから生成されるビット列は

0100
0010 (OR)
0110 (答え)

です。これがdelete関数に渡されます。
渡されたビット列は各ifでビットマスク処理が行われます。

>>45
金庫ならカギかけるじゃん?
馬なら走るじゃん?
金庫は走らないし馬はカギかからないじゃん?
じゃあ型とそれに使う関数には関係があるから
属性値と関数をまとめて型にすればいいじゃん?
オブジェクトじゃん?


すまん俺も初心者だから知らん

>>50
staticおじさん「お前もstaticコーダーにしてやろうか!!」

>>59
Yes

0110はどのifに引っかかるのでしょうか

if (bit & MENU) → 0110 & 1000 → 0
if (bit & HP) → 0110 & 0100 → 1→処理実行
if (bit & WEAPON)→0110 & 0010→1→処理実行
if (bit & ARMOR)→0110 & 0001→0

狙った通りの動作をしてくれています。

>>63
@ITのあの人思い出した
しかもあれで本気そうだったし
あの時はstaticおじさん以外にも色々とぶっ飛んだ人ばかりだったな 今はどうか知らんが

これってわざわざ8ビットとか使わなくても オブジェクト化すればよくね?

やっと多様性と継承辺りを理解したところだけど
〇〇を××するのが手続き型で
〇〇に××させるのがオブジェクト指向だってさ

これがビットマスクです
しかしこれだとビットを意識したプログラミングが必要になります。
やや面倒です。

もっと扱いやすい整数型を使って実現していきましょう。

>>62
ありがたいが喩え話は各方面で耳にたこができるほど聞いたなw
オブジェクト指向の概念自体はわかるんだが実際のプログラミングでどういう設計にしればいいのかわかりにくい
ファイル読み書きのStreamなんちゃらとかすげーめんどいしなぁ Cの簡素さに惚れ直したわ

何言語の講座?

ここで登場するのが「シフト演算子」です。
おそらくプログラミングを始めたばかりの人は全く使ったことがないのではないでしょうか?

x << 1

この「<<」がシフト演算子です

>>65
生島勘富とか(遠い目)

HPと武器(and)を渡すのに
HP | WEAPON(or)なのは気をつけないといけないな

>>66
速度は知らないけど
メモリサイズは変わってくるんじゃね

/*わかんなくても動きゃええねん*/

>>67
これわかりやすいな

シフト演算子とはなんでしょうか?
「ビット列を右または左にずらす」
これがビットシフトです。ビットシフトを行うために使うのがシフト演算子です。

例えば x = 00000001 というビット列があったとします。
これを左に1つシフトさせます( x << 1)
すると x = 00000010 というビットになります
2つシフトさせてやれば
x = 00000100
です

もうお分かりですね。
単にビットをずらしているだけです。

現役バリバリプログラマーだが
>>1が何言ってるからさっぱり分からん

>>29
亀レスだがサブネットマスクも
ホストアドレスとのANDでネットワークアドレスになるって意味ではマスクじゃね

言語はpythonからやれってエリックレイモンドに言われた

>>77
おまえビット処理したことないの?

シフト演算子で値はどのように変わるのでしょうか?
2進数ではなく馴染み深い10進数になおして見ましょう

00000001

これは10進数では「1」です
1つ左にシフトさせます

00000010

これは10進数では「2」です
さらに1つ左にシフトさせます

00000100

これは10進数では「4」です
さらに1つ左にシフトさせます

00001000

これは10進数では「8」です
もうお気づきではないでしょうか?

>>69
ストリームさんはファイル処理のことを何も知らない僕のお願いも聞いてくださるのです

>>58
じゃあC++風に雑にやると
手続き型指向
AddData(int a , int b)
{
  int c;
  c = a+b;

return c;
}

オブジェクト指向
class Data
{
 int a,b;
 int c;
 
 void Add()
  {
    c = a+b;
  }
};

よくある例え話で猫クラスがニャンニャンしてるのは余計に混乱するだけ
マイクロソフトのサンプルとか覗いてみると面白いよ

1からは自己満足な学生側を全く向くことのなさそうな先生という印象しか受けない
理解を図る気が全く感じられない

左に1つシフトすると「値は2倍になる」
左にnつシフトすると「値は2^n倍になる」

「1」を考えます
左に1つシフトした「2」これは「1 * 2 = 2」で2倍ですね
さらに左に1つシフトした「4」これは「2 * 2 = 4」2倍ですね
「1」から考えればこれは左に2つシフトしてることになります
つまり「1 * 2^2 = 4」

ということがわかります

8回でこれって 今までどんな内容やってきたのか見当つかんな

javaだとよくget○○ってそのインスタンスの変数を得るだけのメソッド使うじゃん
あれもオブジェクト?

>>82
なんかブラックボックス化されてる感あるよね

>>83
サンプルかぁ 確かに参考になりそうだな トンクス

String val = object.getValue();
System.out.println(val.substring(1));

ではオプションをわかりやすくしてみます
次は食べる関数に食べ物を渡します

int apple = 1 << 0;
int orange = 1 << 1;
int banana = 1 << 2;
int grape = 1 << 3;

eat(apple | orange);

void eat(int fruits)
{
if (fruits & apple) {
//りんごを食べる処理
}
if (fruits & orange) {
//みかんを食べる処理
}
if (fruits & banana) {
//バナナを食べる処理
}
if (fruits & grape) {
//ぶどうを食べる処理
}
}

特殊な型を必要としていません
整数型だけで実現できています

プログラミング勉強して実力付けて、上手く就職できても時給\350の仕事にしか就けないんでしょ?
じゃ何も勉強しなくて飲食系とかに就職したって大差ないよね?

>>87
オブジェクトってのはインスタンスもしくはオブジェクト指向の概念そのものを指すのでは
getInt()みたいなのはそのクラスから出来上がったインスタンスに対して作用するメソッドの一種(インスタンスメソッド)だよね

さらにビット演算、シフト演算は通常の計算より高速であることがメリットしてあげられます

2倍するプログラムとシフト演算の速度を比較してみましょう

>>85
先生、シフト演算でオーバーフローを起こすことは無いのでしょうか

ブラックボックス化もオブジェクト指向の特徴じゃん
関数のモジュール化なら手続き型でもできるけど
多態性で更に謎が深まってる感じ

>>88
ストリームさんを信じるのです
ストリームさんならやってくれます

>>92
すまん外部からインスタンス変数を知りたいときに
変数を隠蔽してわざわざインスタンスメソッドでgetさせるのは
オブジェクト指向?って質問したかった

>>91
プログラマーになる人間はプログラムを書きたいからプログラマーになるのであり、
飲食系に就職する人間は店舗のマネジメントやサービスに関わりたいから飲食系に就職するのである
これは、アニメーターやデザイナーでも同じこと

時給換算の賃金や待遇なんかを気にするような輩は、公務員やビル清掃の正社員にでもなればよろしい

>>97
なるほど カプセル化ってやつか ぼくがみたさんこうしょにはたしかかぷせるかもおぶじぇくとしこうのとくちょうだとかいてありましたねはい

>>97
外部からインスタンス変数を知りたい←これがまずオブジェクト指向じゃない

#include <stdio.h>
#include <time.h>
#define LIMIT 1000000000

int main(void)
{

clock_t start, end;
start = clock();
for (int i = 0; i < LIMIT; ++i)
{
int count = 1;
count *= 2;
}
end = clock();
printf("[通常の掛け算]%f秒かかりました¥n",(double)(end - start)/CLOCKS_PER_SEC);

start = clock();
for (int i = 0; i < LIMIT; ++i)
{
int count = 1;
count <<= 2;
}
end = clock();
printf("[シフト演算]%f秒かかりました¥n",(double)(end - start)/CLOCKS_PER_SEC);

return 0;
}

>>97
人によるけど俺はそうなんじゃねと思ふ
外部から知りたくなる状況ができちゃうのは好ましくないけど

>>99>>100
なるほどサンクス

じゃんけんができるゲームを作って諦めた

>>93
お前の中の時計は1999年12月31日で止まっているのな

結果を見ればシフト演算のほうが早いことがわかります
理由は明白です。
皆さん御存知の通りコンピュータは2進数で動いています。

シフト演算子はよりプリミティブな操作に近いのです

オーバーヘッドが少ない利点があります。

(しかし現在の高性能PCでは意識するほどの誤差ではありません)

>>13
年齢を知りたいときあなたの頭を覗きますか?
他の人は年齢を知ろうとするとき
年齢は?って聞きますよね
それがgetOOO()メソッドというメッセージ
聞かれる人間がオブジェクト

>>101
count <<= 1; な

あと32ビットintな環境だとおかしいとか、
コンパイルオプションで最適化を無効にしないと多分両方ともほぼ0になるとか

>>106
お前わざとやってんの?本気なら頭かなりイッてるぞ

>>102
そうだよね図しっかり描いて考えてみる

変数を弄る時にsetっていうメソッド?を噛ます事には意味があると思う
だから公開するよりはsetgetでやった方がいいはず
でも>>100なのかぁ

>>98
そもそもプログラマーって言うほどブラックばっかなわけでもないよね
知り合いから話聞く限り仕事さえこなせば勤務場所自由みたいな感じで
割とホワイトなとこもあるみたいだし 2chでブラック伝説が流行り過ぎたのでは

こういう教授居るよね

>>111
初めにInitメソッドだかで渡すもの渡したら最後まで中身に触れる必要なしってのが理想かと

以上で第8回「ビットマスク」は終了です

ご清聴ありがとうございました。

ご清聴(皮肉)

>>115

第9回は「遅延評価」

>>115
おつおつ

この説明で理解したっていう人はものすごく補完能力が高いか何もわかってないかのどちらか
かなり古い教科書のコピペじゃないのこれ

インスタンス変数はとりあえず private で宣言
参照が必要なら ゲッタ だけ宣言

隠蔽をベースにスタートするのがモダンプログラミングだと思う

とりあえず乙

>>111
OOP的には、そもそもgetter/setterで取ってくる先が何なのか気にしなきゃいけないのが間違いなのよ
インスタンス変数を取得するgetterでもいいし、
DB問い合わせを行うgetterでもいいし、
祈祷師に値を教えて貰って返すgetterでもいい

兎に角、getter/setterこそが真であるのがOOP

もう一回強度ケツ合度から出直します

乙 1~7もあるの?

第1回目じゃん

大学で必修の実習でプログラミングをファイルポインタと自分で関数を作るとこまでやって興味わいたんだけど
自学で次に何やればいい?

>>111
恐らく「外部から」って言葉で勘違いしてるんだと思うんだが、
データのやり取りに使うクラスのインスタンスだったら普通にアクセサメソッドで保持してる値を設定、取得するぞ
クラスのアクセス修飾子としてpublicが指定してあったら
そもそも外部(他パッケージ等)からアクセスされることを想定してる訳だし

>>127
言語は?
Cなら構造体とポインタ

なんか勉強になったような気もしなくもない

>>111
OOPってのはオブジェクトが中心ってことだからね
インスタンス変数にアクセスしようとすることが悪じゃない

>>129
C言語、教材はC言語プログラミングの初歩の初歩ってやつ使ってた

>>107
の安価は>>97

>>127
CUIで動くRPGゲーム


電気工作始めたからよく使うわ

>>127
何か作ってみる

>>134
サンクス

これでセンター数学満点取れる様になる?

>>123
「インスタンス変数が知りたい」じゃなくて
「このデータが知りたい」(まぁそのデータは内部的にはインスタンス変数なんだけどね)
なら全く問題ないということでOK?

>>138
PC使えば余裕余裕

カプセルかするのがクラスなんですよ
オブジェクト指向っていうのは内部でどんな変数が居るのか
どんな処理がされているのかは知らないが
これにコレを渡して呼び出すとコレが返ってくるとか
その後コレにアクセスするとコレが手に入るとかこれにセットしておくと
処理に使われるとかそういうものなんですよ
クラス内部の変数まで知りたいって言うのはオブジェクト指向ではない

>>138
ならない

センターはBASICだから関係ないな
そもそもセンター数学はプログラミングしか出ないわけじゃないし、
そのプログラミングも他の単元でやった事をプログラムで計算するとどうなるかって話だし

>>139
インスタンス変数なんかもどうでもいい
クラスと使う側から見れば中がどうなっているのかはどうでもよくって
コレにアクセスするとコレが手に入るっていうだけでいい

>>139
それならおk

なるほど
中の変数が~~って言ってる時点でだめなのか

おーい>>1
ビット演算の変数は符号無しでやらないとダメだぞ
理由は演算オーバーフロー防止の為

>>141
なーるほど

>>139
OK

例えばあるオブジェクトにファイルがロードされているか調べたい

昔はファイル名の変数調べてnullかどうかを調べるみたいにしてた
今は isLoaded() 関数にアクセスして調べるみたいな

isLoaded関数の中ではファイル名の変数調べてnullならfalse、そうじゃないならtrueを返すみたいな処理してる

つまるところやってることは昔と同じ
ただそれが内部的に行われているのかどうかがポイント

>>97
単純なgetter/setter書かされてるから勘違いしてると思うんだけど、
getterとインスタンス変数は別に1対1じゃなくていいんやで

class Temparture {
 private double celsius;
 /* コンストラクタとかは省略 */
 double getCelsius() { return celsius; }
 double getKelvin() { return celsius + 273.15; }
}

上記のように温度を表すクラスがあるとして、getCelsiusはセルシウス温度くれ!って要求な訳じゃん
今たまたま内部表現がセルシウス温度だからそのまま返してるけど、
getCelsiusを呼ぶ側はTempartureクラスのメンバ変数celsiusの値が欲しい訳じゃなくて、
あるTempartureクラスのインスタンスが表している温度をセルシウス温度として要求したいだけなんだ
呼ぶ側がクラスの中身について知る必要はないんよ

>>147
お前をこの世からオーバーフローしたい

既に分かりやすい説明が出てた死ぬ

まあでもこの手の回答って分かる人にはわかるけどわからない人には分からないままだよな

結局プログラミングの数こなしてなんとなく見につけていくしかない

>>83
どう違う?

>>153
確かにな

「オブジェクト指向わかります! カプセル化も完璧です!」って主張する人の何割が、
カプセル化はメンバー変数をprivateにしてgetter/setterをつける事じゃないと理解してることか

>>155
カプセル化をより正確に言い表すとどうなるんですかねぇ

class Temp{
private int a;
private int b;
public int setANum( int num ) { a = num; }
public int setBNum( int num ) { b = num; }
public int sum{ return a + b; }
}
とかでも別にいい
セッターゲッターは必ずペアで作らなきゃいけないわけじゃないし
どっちかだけでもいいし内部的に何をされてようがこの場合は
setANumとsetBNum呼び出して値をセットしてからsumを呼び出すと
setANumでセットしたのとsetBNumでセットしたのが加算されて返ってくるっていうことだけでいい
出来うるだけ上位レイヤーで余計なことを考えずに済むようにするのがクラスの基本
だから、クラスごとにそれぞれ出来ることを限定化する設計とか色々ある
今はオブジェクト指向が正しいっていわれているだけでオブジェクト指向が正義なわけでもない

>>156
getter/setterでアクセスすること、のみでいいんじゃね?

>>157
>setANumとsetBNum呼び出して値をセットしてからsumを呼び出すと
>setANumでセットしたのとsetBNumでセットしたのが加算されて返ってくるっていうことだけでいい

そのこととクラスの内容が完全に一致してるじゃん
この場合仕様を知り尽くしてることと同義じゃん

結局、オブジェクト指向がでてきたのって
Aっていう処理をGUI側に実装していた場合変数が変わらなくても
内部ロジックへの修正が入ってしまうのでGUI側から全て再検証になってしまうとかあるんだよ
で、そうすると面倒だからじゃあクラス内部にこれとこれをこうするとこうしておこうってなると
出入り口が変わらない限りは内部のロジックがどうかわっていようが
それはGUI側への影響はでないって考えになってロジック部のテストだけですむようになるとかね

カプセル化は変数の遮蔽でしょ
触れる場所を限定にするとかやって変数の変更を最低限にするとか。
初心者はすげぇフォーカスのなげぇ変数作りがちだけどフォーカスっていうのは最小限にするべきなんだよ
で、クラスは別にクラスとして持たせておけばいいと。

さっきのは理解はしているが身についてないという奴だった

オブジェクト指向初心者はこれ作れっていうお題無いのかな
FizzBuzzみたいな

>>158
アカン


内部状態を隠蔽して、外部に対してはインターフェースのみ公開すること とか?

>>159
別に実際aとbが違う名前でもなんでもいいし
あくまで表面的にそれぞれに値を設定出来る物だと考えれば
■+□=△
っていう概念をクラス化するとそうなるっていうだけ

>>158
袋とじにされるのは変数に限った話じゃあないってことですね

>>156>>158
カプセル化ってそもそも隠蔽のことじゃないだろ
オブジェクトとしていろんな処理やら変数をまとめること自体をカプセル化
隠蔽はカプセル化の一要素であってカプセル化 = 隠蔽ではない

>>159
「偶然」一致してるだけに過ぎないだろ

class Temp{
private int a;
private int sum;
public int setANum( int num ) { sum += num-a; a = num; }
public int setBNum( int num ) { sum = a + num; }
public int sum{ return sum; }
}

でもいいんだから

>>150
なるほどなるほど
celciusって内部変数はしらないけど
getCelsiusすれば摂氏温度が、getKelvinすれば華氏温度が得られることさえわかってればいいのね

じゃあもしも呼び出し側が温度自体を必要としてなくて
「熱いか寒いか」の判断だけがほしければ
わざわざgetCelsiusして呼び出し側でifで判断しなくても
Temperatureクラスに寒暖を判断するメソッドつくってその値だけ、
つまり呼び出し側で使うデータだけ返してやればいいんだよね?

>>161
ワン、ニャー

>>161
車クラスを作る

>>165
おおう失礼、俺としたことが……

俺がクラスの勉強に作ったのは
シンプルファクトリーパターンで作ったベクターフラフィックスだったな・・・

>>167
イエス

>>165
あれそうだったっけwww
分からなくなってくる

カプセル化はさっきから言ってるように
中身がすり替わってもバレないってのも重要ではないかと

>>165
んじゃあある意味クラスの存在そのものがカプセル化を担っている、的な感じになるんですかね
言われてみれば確かにメソッドや変数にクラスを被せる様子って"カプセル化"っぽいな

んじゃ次回講座はデザパタよろしく
今でも需要有ると思うよ

>>167
その通りだが、その場合は寒暖判断クラスを別途作るべきだな

>>176
今でも確かに需要あるな

2次元ベクトル2つ作って内積求めろ

非OOP

int x1, y1, x2, y2;
x1= 2;
y1 = 3;
x2 = 4;
y2 = 5;

printf("%d", x1*x2 + y1*y2);

OOP

Vector v1 = new Vector(2, 3);
Vector v2 = new Vector(4, 5);

printf("%d", v1.innnerProduct(v2));

デザインパターンは興味ある

>>167
言いたい事がうまく伝わったようで良かった
でもgetKelvinで返ってくるのは華氏じゃなくてケルビン……(華氏はファーレンハイト)

>>177
そこまで必要なん?

デザインパターンは5個くらいしか覚えてない

組み込み系ならいいけどスクリプト系だとクラスを細かく分けるのはダメだね
言語による

Cから入った友人がclassの存在でつまずいてたなあ

>>172ありがとうなんとなくわかってきた気がする
気がするって時点でお察しだけど

getter/setterは1対1じゃなくていいっていうのは
たとえば環境クラスに温度、湿度、騒音なんかの変数があって
それぞれのセッタはあるけどゲッタはそれらから計算される快適指数だけ
みたいなイメージでいい?

>>179
Cでもこうなるんだけど

Vector v1 = {2,3};
Vector v2 = {4,5};

printf("%d", innnerProduct(v1,v2));

singletonが大好き

>>185
うーん。ちょっと違うな

ビットマスクは使ったことないな
シビアなリソース管理が必要なときくらいじゃないと必要にならないんじゃないか

>>186
それは内積を求めるという処理がベクトルそのものに含まれていないからOOPとは違うってことになるのでは

>>181
ここで間違えたおかげでリアルで恥かかなくてすむ、とプラスに考えるわ

>>188
ふえぇ……むずかしいよう
勉強しよう……

>>189
C++だとパラメータ指定とかでドンドコ使うお

>>182
温度と寒暖は別の概念だろ?
「人間にとっての寒暖を判定するクラス」
「タンポポの種にとっての寒暖を判定するクラス」
「フィンランド人にとっての寒暖を判定するクラス」
とかいろいろあるが、温度は「様々な温度単位を相互変換するクラス」だけあればいい

快適指数は環境に所属してるのか

基礎プログラミング講座おまけ「デザインパターン"メディエーター"」

おまけ講座です。
デザインパターンの意義とその一つである「メディエーター」の講座です。

>>193
おおなるほど
寒暖のクラスってイメージが浮かばなかったけど視点で分けるのね

このスレ見てると"class"っつネーミングの妥当性がよくわかる
本当にclassifyが重要なんだな たかだが寒暖を判断するだけでここまで面倒な話になるとは

デザインパターンとはなんでしょう?
文字通り、デザインのパターンです。
なんのデザインでしょうか?答えはクラス設計のデザインです。
このパターンでクラスを設計すると便利だよ、能率的だよ、というのがデザインパターンです。

あくまでデザインパターンはデザインパターンです。
コードは登場しません。
抽象的で概念的な説明に尽きますが、クラス設計をする上でとても重要になっていきます。

今回はその一つである「メディエーター」パターンを説明していきたいと思います。

>>198
これはタイムリーすぎる ぜひとも受講したい

>>193
扱う概念?によってクラスを分けていけばいいのかな
温度なら数値とその数値の単位変換ぐらい

寒暖判断は「判断をする」という機能だけを持ったクラスにわけるべきなのね

>>196
こうしておくと、例えば
「部屋の中にいる人を判別するクラス」が判断した結果を元に適切な「寒暖を判定するクラス」を作り、
「部屋に自動で暖房をつけるクラス」に渡すことで部屋の暖房がついたり消えたりする
みたいな動作をOOP的に表現することができる

メディエーター(mediator)を辞書で引くと「仲介者」と出ます。

ではどういうパターンなのでしょうか?
一つ例を挙げます。

オブジェクトが100個あるとします。
これらのオブジェクトはすべて互いに関連しあっています。
オブジェクト1はオブジェクト2~オブジェクト100まですべてのオブジェクトと関連しており、
オブジェクト2はオブジェクト1、3~100まですべてのオブジェクトと関連しています。

オブジェクト2~100はオブジェクト1の「hoge()」という関数を利用しているとします。
ここでオブジェクト1の仕様が変わり、例えば関数名が変わるとか、処理が分けられるとかが起こったとします。
オブジェクト2~100はhoge()という関数を利用しているためオブジェクト1の仕様が変わるととたんに動かなくなります。
エラーを吐けばまだいいですが、下手に動いてしまうことさえあります。

これは致命的な欠陥です。

>>200
OOP的に正しいことが、実際のプログラミングでそうすべきかどうかはわからんけどな
絶対に温度でしか寒暖判定を行わないとわかってれば、寒暖判定クラスなんてなしで基準温度さえあればいいわけだし

ただ、あえて寒暖判定クラスを別にすることで、
例えば天候や湿度や本人の健康状態なんかも加味した上で、
気温を与えると寒暖判定ができる、みたいな事がやりやすくなるわけだ

メディエーターパターンはオブジェクトの関連についてのパターンといえます。
オブジェクトの関連について仲介をするクラスを用意する。
これがメディエーターパターンです。

[オブジェクト1] [メディエーター]←オブジェクト1のデータください←[オブジェクト2~100]

[オブジェクト1]←あなたのデータください←[メディエーター] [オブジェクト2~100]

[オブジェクト1]→どうぞ→[メディエーター] [オブジェクト2~100]

[オブジェクト1] [メディエーター]→どうぞ→[オブジェクト2~100]

これがメディエーターパターンです

なんかオブジェクト指向!って感じのするパターンな気がする

メディエーター?

そんなんそれぞれのオブジェクトの状態で振る舞いを決めるクラスって事よ
要するに クラス同士の if をまとめたクラスつーこった

if が増えたなー とか あのクラスとクラスに干渉したいけど
自分の中のクラス内やると依存性が高くなるし長いしやりたくないなー って時に使うわけ

教科書的な長ったらしい説明なんざいらんわ
わかってるなら簡潔に説明せいや

これの何がいいのでしょうか?

例えばメディエーターに「getObject1Data()」のような関数があるとします。
これはオブジェクト1のhoge()を実行して返り値をそのまま返すものだとします
つまり

foo getObject1Data()
{
return object1.hoge();
}

これだけの関数です。
この場合、オブジェクト1の仕様が変更になり、以前と同様のデータを得るためにはhoge()で返ってきた値をfuga()関数に入れてやらないといけなくなったとします。
以前だと2~100のすべてのコードが変わりましたがメディエーターパターンだとメディエーターの中身を変えるだけでよくなります

foo getObject1Data()
{
bar = object1.hoge
return object1.fuga(bar);
}

2~100は依然として「getObject1Data()」を使い続けます。

これがメディエーターパターンです。

   / :/  ...:/:′::/ :.:.:.....:./.:/:!:.:.:.i:..!:.:.....:{:.:.:.:.:.:ハ    /
.  /.〃/:...../:′'.::|:: i .::.:.:.:| :i:_{__|:.|:.:.:.i :|:.:.../  ̄`ヽ/      ふ
  '://:′::/斗:十 |::.::.::.:.:.:.: :}}ハ ::ハ:{:≧ト|:::/  な       な な  ぅ
 {//::{: /|i:八::{=从:{ i::::: :N孑弐{ミト∨:::|::′  る.     る .る (
.  i :从 ::::{イァ:う{ミト爪ト::::. ! ん):::::ハヽト、:{:|    ほ      ほ ほ  )
.  |.::| : \《 { ::::::: }  ヽ\{ { ::::::::: リ | :::ヽ!   ど     ど ど む
.  | ::!::|ハト.乂__ノ       ー '  | :::<    |
 八::| :|::::i /i, ,     ,     /i/ , }:::}i::人   __ ノ\
  (__):::l:::::.                 i.:/::::::::厂「{:::::::{    ` ー― ´
 / :{ | :V:入     { ̄`ソ      }/}::::}/::::::l.|:::::::|
 { ::|人::∨::::>...   `      . ィ升|:::/::::::::八::::::{

インターフェイス部と実装部をクラスで分けるってことか

デザインパターンはクラス設計する上で利便性・能率性・保守性などがアップするようなパターンをまとめたものになります

興味がある方はぜひ調べてみてください

>>209
もしかしてメディエーターパターンの話?

>>209
違う

なるほど

あと上でもちょっと話題になってたけど、クラスの機能ってのは基本的に細分化するものなの?
解釈次第でどうとでも"分類"できると思うんだけど、良しとされている傾向みたいなものがあるのか、
それとも本人の好みで好きなようにクラスをつくっちゃっていいのか、はたまたケースバイケースなのか

>>213
プログラムを組む上で一番便利な位置で細分化する
同じような機能でもプロジェクトAではこの機能が4つに分割されてるけどプロジェクトBでは分割されてないみたいなことはある

ケースバイケースが答え

>>214
やっぱり一概には言えないよね ありがとう色々と勉強になった

あら違うのか
公開してる関数を間接的に使うことで修正が楽になるってこと?
分かってるつもりなんだがちょっと違うのかな

このSSまとめへのコメント

このSSまとめにはまだコメントがありません

名前:
コメント:


未完結のSSにコメントをする時は、まだSSの更新がある可能性を考慮してコメントしてください

ScrollBottom