質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

解決済

1回答

645閲覧

[カプセル化]getterを利用せずに範囲内判定を実装できるか

FBF

総合スコア1

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

0クリップ

投稿2023/03/24 12:22

実現したいこと

getterを利用せずにPlayer::isInWorld()を実装したい。(可能なら)

前提

「アクセッサ書く実装は真のカプセル化ではない」、「本番の開発でgetterを書くことは99%ない」などの記事や動画を拝見させていただきました。そこで示されている例題などは納得しました。アウトプットのために、自分でもgetterを使わずにクラス設計できるか試してみました。

発生している問題・エラーメッセージ

そこで、プレイヤーが世界(ある範囲)の中に存在するかしないか、というメンバ関数を実装しようとしました。直面した問題が、「座標クラス(Point)のデータメンバにgetterを書かないと範囲内かどうか比較できないのでは?」というものです。

該当のソースコード

c++

1#include <iostream> 2 3// 座標(x,y) 4class Point 5{ 6public: 7 Point(int x = 0, int y = 0) 8 { 9 m_x = x; 10 m_y = y; 11 } 12 13private: 14 int m_x; 15 int m_y; 16}; 17 18 19// 2次元世界(ただの四角形) 20class World 21{ 22public: 23 World(Point start = {0, 0}, Point end = {640, 480}) 24 { 25 m_start = start; 26 m_end = end; 27 } 28 29private: 30 Point m_start; // 始点 31 Point m_end; // 終点 32}; 33 34 35// プレイヤー 36class Player 37{ 38public: 39 Player(Point point = {0, 0}) 40 { 41 m_point = point; 42 } 43 44 // プレイヤーが世界の範囲内に存在するか? 45 bool isInWorld(World world) 46 { 47 //////////////////////////////////// 48 // アクセッサを使わずに実装できるか? 49 //////////////////////////////////// 50 51 return true; 52 } 53 54private: 55 Point m_point; 56}; 57 58 59int main(void) 60{ 61 Player player = {{20, 30}}; // 座標(20,30) 62 World world; // (0,0)..(640,480) 63 64 // プレイヤーは世界の範囲内にいる? 65 bool exist = player.isInWorld(world); 66 67 return 0; 68} 69

試したこと

getterを書いていいなら単純な座標比較で可能でした。getterを書かずに実装はできませんでした。

なぜPlayerクラスに実装しようとしたのか

google翻訳で「プレイヤーは世界の中にいる」を翻訳したら"the player is in the world"と翻訳されたので、主語であるプレイヤークラスに実装することにしました。

補足情報(FW/ツールのバージョンなど)

コンパイラ: g++

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2023/03/24 13:20

> 「アクセッサ書く実装は真のカプセル化ではない」、「本番の開発でgetterを書くことは99%ない」などの記事や動画を拝見させていただきました。 その記事や動画は正しいんですか?
FBF

2023/03/25 03:53

記事や動画内の例において、「隠蔽」という意味では正しいと判断しました。このgetter不要論は海外でも国内でもあるようです。
Zuishin

2023/03/25 04:03

不要論は文脈が違うので、それに基づいた個人的判断を根拠にしているのであれば、間違っている可能性も低くありません。 他に根拠はありますか?
FBF

2023/03/25 06:24

間違っていても、間違っていなくても、どちらでもかまいません。この記事の主題は「実現したいこと」に書いてある通りです。よろしくおねがいします。
Zuishin

2023/03/25 07:00

なるほど、好きなようにしたいのであれば、好きなようにするのが一番だと思います。
guest

回答1

0

ベストアンサー

その例ならbool Point::isInRect(Point, Point)を追加すれば良いでしょ。
追記:Worldにも似たようなメソッドがいるよ。

cpp

1bool Point::isInRect(Point lu, Point rd) const { return lu.m_x < m_x && m_x < rd.m_x && lu.m_y < m_y && m_y < rd.m_y; } 2bool World::isPointInside( Point pt ) const { return pt.isInRect( m_start, m_end ); } 3bool Player::isInWorld(World world) const { return world.isPointInside(m_point); }

#Point自体からはあんまし「オブジェクト」って感じはしないんで、getter足してもいいと思うけどねぇ。

投稿2023/03/24 15:45

編集2023/03/25 07:00
matukeso

総合スコア1590

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

FBF

2023/03/25 06:28

ご指定の関数を追加し、Player::isInWorld(World world)を実装しようとしましたが、関数内でworldのデータメンバを参照できず実装できませんでした。もしよろしければ、実装コードを示していただけると勉強になります。 よろしくおねがいします。
FBF

2023/03/25 07:52

追記確認しました。バトンリレーのようにクラス間でデータメンバ値を渡していくことでgetter無しで実装できることがわかり、勉強になりました。この例でならPointは構造体として作成し広義のプリミティブ型のように扱ってもいいかなと思いました。 matukeso様がこのような機能を書く場合はどのようなクラス設計、実装にしますか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問