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

この記事は、[C++ Advent Calendar 2018](https://qiita.com/advent-calendar/2018/cpp) の記事です

前日の記事は@Gacchoさんの[「C言語とC++の同時比較リファレンス」](https://qiita.com/Gaccho/items/fd8db5c393c48ef2a61c)でした
次日の記事は@Linus_MKさんの[「C++ randomライブラリをクラス内で使う方法」](https://linus-mk.hatenablog.com/entry/2018/12/16/150732)です


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

#ちょっとしたおさらい

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

```cpp:test.cpp

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


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

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



#疑問
しかし誰しもそんな事を初めて言われたら、`class`と`struct`が何故**同じ機能**を持っているのかと考えるのではないでしょうか？。
そして大抵その解答として
>「Cの互換性を維持しつつ、ついでに`class`と`struct`が機能的に似ていたから合わせたんじゃないのか」

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

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

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

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

>「何で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`と根本的に違う物になったのになぜ分けなかったのか 理由は以下の通り
    * `struct`と`class`の**概念**を**一つ**にしたかった その方が**円滑に結合**できるし**単純実装**で済む
    * もし`struct`と`class`の概念が**別々**に分かれていたら、**各派閥**に分かれ**犬猿の仲**になってたはず


* またこのような選択を取ったことにより、以下の二つの目的が達成された
    * 「`struct`は`class`である」と言った概念を**定義**する事により、`class`機能の**肥大化**を防ぐことが出来た
    *  **C++**が**C**に程遠い高級言語と言う位置付けになるのを防ぐことが出来た(望んでた人もいるんだろうけど)

*****

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



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

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

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

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