「平成」を感じるもの

仕事ではC言語を使っています。7年ぶりくらいにC++を勉強しなおす気になりました。勉強し始めて疑問に思ったことがあります。

C++では構造体もメンバ関数やコンストラクタ、デストラクタをもてるようですが、なぜそのような仕様になったのでしょうか?クラスでできることをわざわざ構造体(や共用体)でも出来る必要性を感じません。(きらいなら使わなければいいだけのことですが。)

学生時代にC++を勉強したとき使っていた本(※)にそのような記述が無かったような気がします。
※柴田望洋著:プログラミング講義C++、ソフトバンクブックス、1997

なぜそのような仕様になっているのか、経緯や必要性について教えてください。

A 回答 (5件)

質問者さんがお望みのこと全てではありませんが、D&E (C++の設計と進化)という本の


94~95ページに、なぜclass と structという二つのキーワードが
ほぼ同じ機能を持っているのかということについての説明があります。

詳しくは買うなり図書館に行くなりして実際に読んでもらうとして、
簡単にまとめると、structをCでの機能をのままにすることによって
C++文脈でのclass、C文脈でのstructというように概念的に二つに分かれて
しまうのを嫌がったということのようです。

この本には、「なぜC++は××に関してこのような仕様になっているのか?」
についての回答が得られる貴重な本です。
余裕があれば読んでみると良いでしょう(分厚いけどね)。

C++の設計と進化 (単行本)
ビョーン ストラウストラップ (著), Bjarne Stroustrup (原著), 岩谷 宏 (翻訳), エピステーメ (著)
http://amazon.jp/dp/4797328541
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

ご紹介いただいた本、魅力的なのですが分厚いのはやや難ですね。購入するにしても今参考にしている「独習C++」(やっぱり分厚い)をやっつけてからになりそうです。

お礼日時:2007/03/15 22:48

クラスと構造体の(実装ではなく)理念上の違いはご理解されているということで良いかと思います。



その上で、「構造体」とは、あくまでもまとまったデータセットです。
このデータセットを「安全に」初期化するためには、コンストラクタというのは、十分に実用的です。
特に、構造体の初期化データを外部から持ってきたり、外部に(暗黙のうちに)保存したりという操作を行うためには、コンストラクタやデストラクタは必須の機能になります。

また、データ特有の操作についても、メンバ関数は有用です。

「クラスでできることをわざわざ構造体でもできるようにした」のは、本来の意味からすれば、クラスと構造体は、別の用途であるので、それぞれの用途に於いて、「統一的に」初期化や後始末や、そのほかの処理が行えるようにしたというところです。

参考URL:http://www.cmagazine.jp/src/kinjite/cpp/idea.htm …
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

> このデータセットを「安全に」初期化するためには、コンストラクタというのは、十分に実用的です。

これは大いに頷けます。

お礼日時:2007/03/15 23:10

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 の関係については、最初から変わっていないと思います。
ので、その本でもウソは書かれていなかったと思うのですが、とにかく、帯に書かれていた宣伝文句とは裏腹に、分りにくい本だったという記憶があります。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

互換性、の一言に尽きそうですね。
互換性を考えなくて済むJavaでは構造体がなくなっているところを見ると、クラスがあれば構造体が無くても済んでしまうということなのでしょう。
(なのに、C#ではまた構造体が登場して訳が分かりません。)

>> ※柴田望洋著:プログラミング講義C++、ソフトバンクブックス、1997
> 今は捨ててしまったので確認できませんが、struct と class の関係については、最初から変わっていないと思います。

本を引っ張り出してきて確認してみたところ、
Column 12-4 クラスと構造体と共用体 に、「(3)メンバ関数を持つことが出来ない」とはっきり書かれていました。
しかし、この本が発行されたのは1996年12月と古いため、ANSI/ISOで標準化されるうちに新しい機能として追加されたのではないかと思っています。

お礼日時:2007/03/15 23:04

C++では、構造体や共用体もクラスの一種です。

クラスなのだから、メンバ関数を持てるのは当然です。

C++のクラスの宣言は、

クラスキー タグ名

という形式で行いますが、このクラスキーに指定できるのは、class, struct, unionの3種類があります。classとstructの違いは、アクセス指定がデフォルトでprivateになるかpublicになるかだけです。unionはメンバ変数のメモリ配置が違ったり、他のクラスから派生したり、派生されたりしない点が大きく異なります。

> クラスでできることをわざわざ構造体(や共用体)でも出来る必要性を感じません。

そういう観点からすれば、structでできるのにわざわざclassを導入する必要はなかったともいえます。
    • good
    • 0
この回答へのお礼

早速の回答ありがとうございます。

> C++では、構造体や共用体もクラスの一種です。

クラスが先にあるのでか。そうなると、CとC++では名前はおなじ struct でも概念は別物(だけどCと同じ使い方はできるようにしてある)と理解しておいたほうがよさそうですね。

お礼日時:2007/03/11 20:59

c互換のためっていうのが一番大きいと思います


structを捨てることはできなかったんでしょう

私はclassと構造体は使い分けてますけどね
(私は、というより今のプロジェクトがそうなっているからともいえる)


http://oshiete1.goo.ne.jp/kotaeru.php3?q=2007539
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

> structを捨てることはできなかったんでしょう

それなら、structに手を加えずそのままにして置けばよかったのに、と思うのは私がCばかり使ってきたからでしょうか。

> 私はclassと構造体は使い分けてますけどね

私は
 クラス = データと振る舞いをセットにしたもの
 構造体 = (関連の深い)データのまとまり
と理解していたので、構造体が振る舞いをもったり、継承されたりするとすごく気持ち悪いです。

お礼日時:2007/03/11 21:26

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報