仕事ではC言語を使っています。7年ぶりくらいにC++を勉強しなおす気になりました。勉強し始めて疑問に思ったことがあります。
C++では構造体もメンバ関数やコンストラクタ、デストラクタをもてるようですが、なぜそのような仕様になったのでしょうか?クラスでできることをわざわざ構造体(や共用体)でも出来る必要性を感じません。(きらいなら使わなければいいだけのことですが。)
学生時代にC++を勉強したとき使っていた本(※)にそのような記述が無かったような気がします。
※柴田望洋著:プログラミング講義C++、ソフトバンクブックス、1997
なぜそのような仕様になっているのか、経緯や必要性について教えてください。
No.3ベストアンサー
- 回答日時:
質問者さんがお望みのこと全てではありませんが、D&E (C++の設計と進化)という本の
94~95ページに、なぜclass と structという二つのキーワードが
ほぼ同じ機能を持っているのかということについての説明があります。
詳しくは買うなり図書館に行くなりして実際に読んでもらうとして、
簡単にまとめると、structをCでの機能をのままにすることによって
C++文脈でのclass、C文脈でのstructというように概念的に二つに分かれて
しまうのを嫌がったということのようです。
この本には、「なぜC++は××に関してこのような仕様になっているのか?」
についての回答が得られる貴重な本です。
余裕があれば読んでみると良いでしょう(分厚いけどね)。
C++の設計と進化 (単行本)
ビョーン ストラウストラップ (著), Bjarne Stroustrup (原著), 岩谷 宏 (翻訳), エピステーメ (著)
http://amazon.jp/dp/4797328541
回答ありがとうございます。
ご紹介いただいた本、魅力的なのですが分厚いのはやや難ですね。購入するにしても今参考にしている「独習C++」(やっぱり分厚い)をやっつけてからになりそうです。
No.5
- 回答日時:
クラスと構造体の(実装ではなく)理念上の違いはご理解されているということで良いかと思います。
その上で、「構造体」とは、あくまでもまとまったデータセットです。
このデータセットを「安全に」初期化するためには、コンストラクタというのは、十分に実用的です。
特に、構造体の初期化データを外部から持ってきたり、外部に(暗黙のうちに)保存したりという操作を行うためには、コンストラクタやデストラクタは必須の機能になります。
また、データ特有の操作についても、メンバ関数は有用です。
「クラスでできることをわざわざ構造体でもできるようにした」のは、本来の意味からすれば、クラスと構造体は、別の用途であるので、それぞれの用途に於いて、「統一的に」初期化や後始末や、そのほかの処理が行えるようにしたというところです。
参考URL:http://www.cmagazine.jp/src/kinjite/cpp/idea.htm …
回答ありがとうございます。
> このデータセットを「安全に」初期化するためには、コンストラクタというのは、十分に実用的です。
これは大いに頷けます。
No.4
- 回答日時:
No.1 の方の回答のとおり、互換性のためだと思います。
既存のCのソースコードに「一切手を入れずに」、修正したり拡張したりする、ということがC++言語仕様策定の重要な要件(作者の)だったと思います。
C++作者の「プログラミング言語C++」(今は第3版?)等を読むと、作者の思いなども書かれていて、とても面白いですよ。
私の独断ではありますが、今では単なる syntax sugar に過ぎなくなっているので、struct の構文は要らないです。
私自身は、すべて class で記述しているので。
ただ、既存の(昔作られた)ライブラリなどをコンパイルするためにはいきなり無くなってしまうと困る、皆様そんなかんじではないでしょうか。
MFCなどを考えて見ると、CPoint等、簡単なものについてはわざわざstructにしてますが、最初うっかりやってしまった後の互換性のため、やむを得ず、ということだと思います。
本質的には全くどうでも良いと思ってます。
> それなら、structに手を加えずそのままにして置けばよかったのに、
> と思うのは私がCばかり使ってきたからでしょうか。
確かに、struct にはメンバ関数は定義できないようにしたうえで、C++としての拡張をしても良かったのかも知れませんね。
ただ。
初期C++言語はCのプリプロセッサとして実装されていたそうで、たぶんコンパイラの実装のことまで考えて妥協した部分もあるのでは?
コンパイラの作成は難しいですし。
> 学生時代にC++を勉強したとき使っていた本(※)にそのような記述が無かったような気がします。
> ※柴田望洋著:プログラミング講義C++、ソフトバンクブックス、1997
私も実はそれを読みました(^^;
今は捨ててしまったので確認できませんが、struct と class の関係については、最初から変わっていないと思います。
ので、その本でもウソは書かれていなかったと思うのですが、とにかく、帯に書かれていた宣伝文句とは裏腹に、分りにくい本だったという記憶があります。
回答ありがとうございます。
互換性、の一言に尽きそうですね。
互換性を考えなくて済むJavaでは構造体がなくなっているところを見ると、クラスがあれば構造体が無くても済んでしまうということなのでしょう。
(なのに、C#ではまた構造体が登場して訳が分かりません。)
>> ※柴田望洋著:プログラミング講義C++、ソフトバンクブックス、1997
> 今は捨ててしまったので確認できませんが、struct と class の関係については、最初から変わっていないと思います。
本を引っ張り出してきて確認してみたところ、
Column 12-4 クラスと構造体と共用体 に、「(3)メンバ関数を持つことが出来ない」とはっきり書かれていました。
しかし、この本が発行されたのは1996年12月と古いため、ANSI/ISOで標準化されるうちに新しい機能として追加されたのではないかと思っています。
No.2
- 回答日時:
C++では、構造体や共用体もクラスの一種です。
クラスなのだから、メンバ関数を持てるのは当然です。C++のクラスの宣言は、
クラスキー タグ名
という形式で行いますが、このクラスキーに指定できるのは、class, struct, unionの3種類があります。classとstructの違いは、アクセス指定がデフォルトでprivateになるかpublicになるかだけです。unionはメンバ変数のメモリ配置が違ったり、他のクラスから派生したり、派生されたりしない点が大きく異なります。
> クラスでできることをわざわざ構造体(や共用体)でも出来る必要性を感じません。
そういう観点からすれば、structでできるのにわざわざclassを導入する必要はなかったともいえます。
早速の回答ありがとうございます。
> C++では、構造体や共用体もクラスの一種です。
クラスが先にあるのでか。そうなると、CとC++では名前はおなじ struct でも概念は別物(だけどCと同じ使い方はできるようにしてある)と理解しておいたほうがよさそうですね。
No.1
- 回答日時:
c互換のためっていうのが一番大きいと思います
structを捨てることはできなかったんでしょう
私はclassと構造体は使い分けてますけどね
(私は、というより今のプロジェクトがそうなっているからともいえる)
http://oshiete1.goo.ne.jp/kotaeru.php3?q=2007539
回答ありがとうございます。
> structを捨てることはできなかったんでしょう
それなら、structに手を加えずそのままにして置けばよかったのに、と思うのは私がCばかり使ってきたからでしょうか。
> 私はclassと構造体は使い分けてますけどね
私は
クラス = データと振る舞いをセットにしたもの
構造体 = (関連の深い)データのまとまり
と理解していたので、構造体が振る舞いをもったり、継承されたりするとすごく気持ち悪いです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
FriendとPublicの違い。。。
-
既定のコンストラクタがない?
-
名前空間について
-
VC++ Express m_hWnd
-
ダイアログ表示時にチェックボ...
-
SetTimerの行でアサートエラー...
-
C#で通常のbuttonコントロール...
-
[MFC] CWnd::MessageBoxの警告...
-
このコンパイルエラーの意味に...
-
【ASP.NET】 独自で作成したク...
-
自作のクラスが参照できない
-
【C++】vectorについて
-
(UWSC) 「#32770」の意味わかり...
-
Delphi2007のCheckBox.Font.Col...
-
OnInitDialog()の関数の組み込み方
-
ダイアログクラスのコントロー...
-
form1 から form2 へのデータの...
-
スプラッシュコントロールの挿...
-
クラスのアドレスを引数として...
-
VC6 コンパイルエラー C2248に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
FriendとPublicの違い。。。
-
既定のコンストラクタがない?
-
(UWSC) 「#32770」の意味わかり...
-
C++ protectedにアクセス不可
-
ダイアログ表示時にチェックボ...
-
エディットコントロールでEnter...
-
【ASP.NET】 独自で作成したク...
-
このコンパイルエラーの意味に...
-
DataGridViewのセルに斜線を引...
-
ダイアログクラスのコントロー...
-
MFCのCListCtrlでスクロールを検出
-
C++で継承元のクラスの代入演算...
-
MFCのドラッグ&ドロップについて
-
イベントにAddHandlerされてい...
-
MFCアプリのコマンドラインでパ...
-
DebugクラスとTraceクラスの違い
-
[MFC] CWnd::MessageBoxの警告...
-
個々の関数について継承してい...
-
クラスのアドレスを引数として...
-
関数の呼び出し元の検索
おすすめ情報