LoginSignup
37
7

More than 5 years have passed since last update.

なぜC++のclassとstructは同じ機能なのか

Last updated at Posted at 2018-12-10

この記事は、C++ Advent Calendar 2018 の記事です

前日の記事は@Gacchoさんの「C言語とC++の同時比較リファレンス」でした
次日の記事は@Linus_MKさんの「C++ randomライブラリをクラス内で使う方法」です

折角招待して頂いたので普段は触る機会の無い物でも使って何か作ろうかと無計画にネタを考えていたら
スプラトゥーンとスマブラに時間を奪われ間に合わなかったので以前知った小話を
皆さんはこんな奴みたいな事にならないようにスケジュール管理はしっかりしましょう!

ちょっとしたおさらい

Qiitaを読んでいるような熟練のC++erの方々ならばとっくにご存知の事かとは思われますが
C++でクラスを表す方法としては、C由来のstructを使う方法と、C++にて追加されたclassを使う方法の二種類が存在します。
C++においてこれらの機能は、アクセス修飾子がデフォルトでpublicprivateかと言う点以外は全く同じ機能を持っています。

test.cpp

//下2つの式の意味は同じ
class test{
    public:
    test();
    int a,b,c;
};


struct test2{
    test();
    int a,b,c;
};

これらの二つのワードで使い分けるべき点は特に無く個人の趣向プロジェクト規約に合わせて使い分けていくのが主でしょう。

疑問

しかし誰しもそんな事を初めて言われたら、classstructが何故同じ機能を持っているのかと考えるのではないでしょうか?。
そして大抵その解答として

「Cの互換性を維持しつつ、ついでにclassstructが機能的に似ていたから合わせたんじゃないのか」

と言った回答に辿り着く事でしょう(もしくは教えてもらうか)
まあ大半の理由はそこに有るでしょうし、そんな事を深堀しても殆ど何も出てこないので皆さんさっさとと他の方向に目を追いやった事かと思います。

かく言う自分も特に深堀せずそっぽを向いて、天より授かりし命を重んじこの人生を全うすべく日々慎ましやかに生活してまいりました。

classとstructで機能が同じである理由

とまあそんなこんなでclassstructが同じ機能である理由なんぞ特に考えずぼけーっと日々を過ごしていたのですが、
ある日某なんとかちゃんねるでこんな質問をしている方がいらっしゃいました。

「何でC++のclassとstructは機能がほぼ同一なのにわざわざ2つ残したんだ?Cとの互換維持が目的ならデータのみ持つのはstruct、メンバ関数も含めるのはclassにした方が機能の重複が無くて有意義じゃないか!」

ううむ…確かに一理あるなぁ
CのstructとC++のclass多少似ている部分は有れどそれまでの使われ方は異なっていた訳だし
折角classと言う新しい概念を作ったのであればstruct切り離してしまった方が機能がより明確になるし
両方のワードが残っている意味も出来て有意義だったのかなぁ…などと思いながら読み進めていたところ、それに対しての回答があり、

「classとstructが同じ理由 探してみたらC++の設計と進化に書いてあったぞ! 読んでみそ」

とのこと…
C++の設計と進化…そういや以前に2,3回読んで本棚にシュートしたな…と思いつつ本棚へいざ冒険
荒波乗り越え見事発見し色々と読んでみた所、C++の設計と進化には以下のように書かれていました。

Bjarne Stroustrup著 :「C++の設計と進化」p94-95より引用
 
…C++の仮想関数のあるクラスのオブジェクトは、Cの単純なstructとは根本的に異なるものである。しかしそれではなぜ、私はこの時点で、structとclassを別の概念にすることを選ばなかったのだろう?
私の意図は、概念を一つにすることだった:レイアウトのルールも一つ、参照のルールも一つ、解決(resolution,名前の解決)のルールも一つにする。ルールを二つにしてもそんなに困らなかったかもしれないが、しかし単一概念の方が、各機能の円滑な結合化と単純な実装を可能にする。structが"Cと互換性"のテーマに属して、classが"C++と高度な機能"に属したら、ユーザグループが二派に分かれ、犬猿の仲になってしまうだろう。
クラスを設計するときは、言語の機能をありったけ使うこともできるし、逆にできるだけ少なめに使うこともできる
…(中略)…その後いろんな人が"クラスだけに"実装できる高価なアイデアを次々と持ち込み、対照的に、structのオーバーヘッドの少ない簡素さが際立った。structとclassを同じ一つの概念でカバーしたことによって、クラスの機能の
過肥大も防げた、と私は信じている。つまり"structはclassである"という概念によって、C++が低レベルのサブセットと絶縁した高級すぎる高級言語に浮揚していくことを防げた、と思うのである。それを望んでいた人もいるだろうが。

要所をざっくりと抜き出すと

  • classは仮想関数を持った時点でCのstructと根本的に違う物になったのになぜ分けなかったのか 理由は以下の通り

    • structclass概念一つにしたかった その方が円滑に結合できるし単純実装で済む
    • もしstructclassの概念が別々に分かれていたら、各派閥に分かれ犬猿の仲になってたはず
  • またこのような選択を取ったことにより、以下の二つの目的が達成された

    • structclassである」と言った概念を定義する事により、class機能の肥大化を防ぐことが出来た
    • C++Cに程遠い高級言語と言う位置付けになるのを防ぐことが出来た(望んでた人もいるんだろうけど)

と言う事でした。
確かにstructclassで概念が分かれていたらややこしくなるでしょうし、分けた事によりどちらの方が優れているかーなどと言う無駄な議論が起こるぐらいなら
多少くすぐったい所があれど概念は一本化したほうがてっとり早いですね。

まとめ

という訳で、classstructが同じ機能を有している事情にはこんな理由があったそうです。

ところで、そんなにclassstruct同一概念にしたいのであればstruct 一本 にしても良かったのでは?と言う意見も出てきそうな物ですが、全く新しい機能が同一の名前でのみサポートされていては混乱を招きかねませんし、
結局は同一の概念にすると言う選択肢が一番ベストだったのでしょう。

結果的に今些細な疑問が持たれることはあれど激しく非難されるような疑問ではないですし、classstructの概念を同一にする選択は正しかったのかもしれません。

補足

ツッコミ、持論、マサカリ等有りましたらどんどん投げてくださると嬉しいです。

37
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
7