A(びーいずあえー)という関係なのでis-a関係です。private継承、protected継承はis-a関係ではありません。is-a関係との対比でhas-a関係、またはis-implemented-in-terms-of関係なんて呼ばれたりします。Aの関係では無いため、AのポインタにBを代入することはできません。0;}基底クラスのポインタへの代入を許すのはpublic継承だけです。public継承以外の継承では基底クラスのメンバへは内部からしかアクセスできません。あるクラスをprivate継承していようが、メンバとしてもっていようが、Bというクラスの実装の詳細の為に内部でAの機能を使うという状態は実際のところ変わりません。あるクラスの持つ機能を使いたい場合にはメンバとして持つ継承するという2つの選択肢があります。基本的に継承はコードの複雑性を増すので避けられるなら避けた方が望ましいとされています。できるだけコンポジション(内包)を使って実装する方が良いでしょう。Optimization)が効くケースがあるという点が挙げられます。これはメモリ効率の観点からすると大きなアドバンテージとなります。2つ目は、あなたがライブラリの設計者で、自作するクラスBは、Aというクラスの仮想関数をオーバーライドして何かしたいけど、ユーザーには自分の作ったクラスをAのポインタとして管理させたくない。何を言っているのでしょうか。0;}これで画面には”B-do”と3回表示されます。実用性を感じない例ですが、あるクラスの一部の挙動をオーバーライドでカスタマイズしたい場合は継承するしかありません。このようなケースは本来ならpublic継承でいいのですが、なんらかの理由(基底クラスのデストラクタがvirtualになっていない等)で基底クラスのポインタによる管理を許さない設計にしたい場合は前述のとおり、public継承しないことで実現できます。STLのコンテナは全てデストラクタがvirtualではありません。これらのクラスを拡張した便利コンテナクラスを作成したい場合も絶対にpublic継承してはいけません。いえ、例えばstd::vectorの拡張クラスを作りたい時に、std::vectorをメンバとして持つと、std::vectorの持つメソッドを全て再実装しなければいけないという手間が発生します。上記のようなケースでは継承とusingを組み合わせることで実装がシンプルになります。0;}boost::noncopyableはデータを持たないクラスなのでEBOが効き、さらにデストラクタがvirtualではないので、private継承にうってつけの例と言えます。{public:Box();~Box();};正解は......この情報だけでは何とも言えない。一見するとダメっぽいと感じる人も多いかと思います。c++のことをちょっと詳しくなった頃の人はまずデストラクタに目が行くかと思います。デストラクタの前にvirtualが付いていませんね。virtualで無いデストラクタは継承してはいけないということはc++で最初に学ぶことの一つです。情報を足して、Objectクラスの定義も見てみましょう。~Object();};シンプルです。virtualが定義されたデストラクタが定義されている模様です。これではっきりしました。Boxはpublic継承しても安全です。「Boxをpublic継承しても安全」という表現をもっと詳しく書くと「Boxを継承したクラスをnewで生成して、そのポインタをBox,もしくはObjectのポインタに入れて、deleteを呼んでも安全」ということです。0;}Objectクラスのデストラクタにvirtualが付いているので、Objectをpublic継承している全てのクラスのデストラクタは暗黙にvirtual指定が付きます。もれなくvirtualになります。これも暗黙にvirtual};一昔前は派生先のメソッドにvirtualをつけることで、継承元のメソッドをオーバーライドしてますよ的なことを匂わせるアプローチもありましたが今はc++11から追加されたoverrideキーワードがあるのでそちらを使いましょう。エラー!基底クラスにないメソッド名!};オーバーライドしている意思が明確になり、より可読性の高いコードとなります。メソッド名を間違えたりしても、今までは間違った名前で新しいメソッドが作られるだけで不具合の温床になっていましたが、overrideキーワードの恩恵で、基底クラスに無いメソッド名を指定した場合はエラーにしてくれます。teppynewは引数でサイズを受けますが、標準のnewはsizeが0でも正しく動作することを規格で定めています。自分で実装する際には意識するとちょっとだけ規格に準じたコードになってよいです。1件のコメント名前を付けるという行為には責任が伴います。子供にせよ、ペットにせよ、変数名にせよ。ドラクエ5で子供の名前を付ける時に、かなり悩んだ経験を持つ人も多いのではないでしょうか。C++でコーディングしている時も名前を付ける機会は多いです。マクロ名にクラス名......他にもとにかく名前を付けなければいけないタイミングは多いです。その都度、ドラクエ5の時くらい悩んでいてはプロジェクトは全く進まなくなってしまうので、直感と経験でサクサク名前を付けましょう。ちなみにここで言及している「名前」のことをC++的に気取っていうと「識別子(Identifiers)」といいます。この識別子には色々ルールがあって、ルールに違反した識別子は使ってはいけません。識別子のルールに違反した場合、コンパイラがエラーにしてくれるものがあります。inlineはキーワードなのでエラー}一部演算子の代替表現?なんだそれは!?C++ではキーワードではないが、ある種の演算子と同意語の単語がいくつか用意されており、それらも識別子として使用できません。演算子の代替表現なのでエラー}これらのルールはコンパイルの段階でエラーになるので、詳細を覚えててなくても大丈夫です。以下のルールはエラーにはなりませんが、C++の予約語のため、使ってはいけません。0;}これらのルールに違反した識別子を使った場合の動作保証は無いので、絶対に使わないようにしましょう。__Japan_987654321_wwww___ssl93jjasf__なんて識別子が被るなんてあるわけないから別に問題ないじゃん!と思ったとしても、避けられるリスクは避けるべきです。言語の規格で使うべからずとされているものは使わない方がいいのです。インクルードガードを書く時にこのルールを犯しているコードをよく見かけます。_HOGE_H__コンパイラがエラーにしてくれないので、書く側で気をつけましょう。ディレクティブは、プリプロセスで解釈され、書かれたファイル名の内容を単にその場所に展開したものとして処理されます。boost.hppの内容が単に展開される一般的にファイルの先頭付近にinclude文はまとめて書く感じですが、コードの中に埋め込むことも可能です。以下のような、動物の名前を列挙しただけのファイル(animals.csv)があるとします。"kangaroo"};と展開されて、普通にコンパイルが通ります。このように#includeディレクティブはとにかく機械的に展開するものだ、という話です。普通に同じヘッダーファイルを複数includeしてしまうと、(機械的に展開するだけなので)includeの数だけその場所に展開されます。include元のファイルに何かシンボルの定義みたいなものが含まれている場合、多重定義エラーになります。0;}なので、一つのコンパイル単位中に同じファイルが複数回、展開されないようにする必要があります。多重に展開されることを防止するには、展開元のファイルに多重展開防止用のマクロ(インクルードガード)を仕込むのが定石とされています。c/c++が標準で提供する全てのヘッダーファイルにはインクルードガードが使われています。INCLUDE_GUARD_HOGE_HPPシンボルの定義名(例ではINCLUDE_GUARD_HOGE_HPP)は、一意に定義される文字列なら別に何でも良いです。複数includeされても、最初の一回以外はINCLUDE_GUARD_HOGE_HPPが定義済みなので単にスキップされますので、include元のファイル内に書かれたクラス定義などが多重定義されてしまう心配はありません。-#endifで囲うインクルードガードを、厳密には「内部インクルードガード」といいます。-#endifの部分をinclude先にも書く手法を「冗長インクルードガード」といいます。INCLUDE_GUARD_HOGE_HPPこのように書くと#include文の評価をする前に、スキップするか決められる為、コンパイル時間の短縮につながる場合があります。困ったことに、コンパイル時に複数のヘッダーファイルが何度も検出されるような状況下では、ヘッダーファイルを開き、#ifndefを評価し、終わりの#endifを走査するプロセスに時間がかかる可能性があります。場合によっては冗長インクルードガードを設定することにより、コンパイル時間を大幅に短縮できます。#62:インクルードガード冗長インクルードガードについては毎回外部に書く手間の割に大したメリットも無いのであまり使われていません。ガードにつかうマクロ名を内部インクルードガードと冗長インクルードガードで合わせなければいけない為、別々のファイルなのに結合が生じてしまいます。内部インクルードガードのマクロ名を変えた場合、冗長インクルード側のマクロ名も忘れずに変えなければなりません。外部の#includeガードは冗長で、現在のコンパイラ上では時代遅れである。インクルードする側とヘッダーファイルがガード名について合意していなければならない。これにより、密接な結合が生じ、脆弱となる。Standards今の時代には不要となった冗長インクルードガードですが、教養として押さえておくと良いでしょう。コモンセンスってやつですね。once言語機能ではありませんが、多くのコンパイラではこの魔法の言葉をファイル中に書いておくだけで複数インクルードされない仕組みを提供しています。インクルードガードを書くより、遥かにタイプ数が少なく済むので単純に楽です。onceによる複数include回避の方法はコンパイラに依存するため、コンパイラによっては使えないこともありますし、コンパイラの実装によっては予期せぬ不具合の原因になる場合があります。あるファイルを複数includeしない為に、そのファイルが既にincludeされたことがあるかをコンパイラは覚えておく必要があります。include済みのファイルかどうかを判定するために、ファイル単位に一意のシンボル名を定義するとします。その一意の文字列生成の為にファイルパスを埋め込んでシンボル名を作るような実装になっていた場合、すごーーーく長いパス(c:/user/xxxxxxxxxxxx/development/my_project/tekitou_na_project_name/game/lib/include/group/category/tekitou_na_header_file_name.hpp)の場合、途中でバッサリとパスが切られて、まったく同じシンボル名になって、初めてincludeしたファイルなのにスキップされるという、なかなか原因解明が困難な不具合に襲われる......といったケースがあるかもしれません。......はい、体験談です。言語標準じゃない機能なので私は使わなかったのですが、あの一件以来、さらに避けるようになりました。コンパイラによる拡張機能で、言語の機能ではないので、これをコード中に書いた瞬間に、そのコードはコンパイラ依存のコードになります。ポータビリティの高いコードを書きたい場合は、単に使わない方が得策です。onceを使わなくても、マクロによるインクルードガードで、コンパイラ依存の無い形で実現出来ますからね。onceも冗長インクルードガードと同様、includeするファイルの中を見に行く前に、以前にincludeしたことがあるかを判定出来るため、若干コンパイル時間が短くなることが期待できます。初学者はC++の勉強の一環として、CryENGINEのソースコードを読んだりすると思いますが、その中でもこのインクルードガードに触れることができます。以下はCryENGINEのあるヘッダの冒頭部分です。once#endifインクルードガードのマクロ名が__で始まっていますが、連続するアンダーバーを含む名前はC++の予約語なので真似するのは絶対に止めましょう。参照:禁忌の識別子スーパープログラマ集団でも平気でC++の規格に違反してしまうところを垣間見て勇気を得た所で先に進みます。onceしているのが分かると思います。onceによって、ちょっとでもコンパイル時間を短縮しようというという貪欲な姿勢が見てとれますね。このようにインクルードガードとの合わせ技で攻めるというアプローチもあるので覚えておくと良いかもしれません。Data)とは、C言語のデータと互換を持つデータ構造のことです。memcpyでデータをコピーできたりするものですが、それは本質的ではなく、とにかくPODの一番の意味はC言語のデータとbitレベルで完全に互換を持つということです。C++とC言語をまたぐプログラムがある場合、受け渡されるデータはPODでなければいけません。会話中での出現例でいうと「あれ、ちゃんとPODで作っといてよ!」という具合に使います。PODとは具体的にはどういうデータ構造でしょうか。C互換データ=PODは、複雑なクラスレイアウトや、構築、コピー、ムーブなどのユーザ定義のセマンティクスを配慮することなく、”単なるデータ”として利用できるオブジェクトである。type)であるこの2つの定義を満たせば、それは紛れもないPOD型です。簡単ですね!それぞれの定義をさらに掘り下げます。標準レイアウト型virtual関数を持たないvirtual継承をしていない参照メンバを持たない非staticメンバに対して複数のアクセス指定子を持たない(重要!)標準レイアウトでない型を継承していない標準レイアウトでない非staticメンバを持たない継承していてもいいが非staticメンバを持つクラスは継承ツリーの中で1つだけしかない4番目の項目に注目してください。クラスの不定なメモリレイアウトでも触れたとおり、複数のアクセス指定子でメンバを定義してある場合、標準レイアウトの保証はなくなります。トリビアル型トリビアルなデフォルトコンストラクタを持つトリビアルなコピー動作およびムーブ動作をする散々登場しているこの「トリビアルな○○」ってなんやねん!と、あなたは言うでしょう。トリビアルなデフォルトコンストラクタを持つ、トリビアルなコピー動作、ムーブ動作をするとは、大雑把に言うとコンパイラ定義のこれらの動作をするということです。コピーコンストラクタをユーザーが定義したら、それはもうトリビアルな型ではありません。引数無しコンストラクタをユーザーが定義したら、コンパイラ定義のデフォルトコンストラクタが無くなるのでこれもトリビアルな型ではありません。さあ、これで自分の書いたクラスがPODかどうか判断できるようになりました。こんなことは忘れてもいいのです。あるクラスがPODかどうか、本当に知りたいのならstd::is_podを使いましょう。std::endl;}}(コンパイラベンダーの実装にバグが無い限り)正確にPODの判定をしてくれます。小難しいことぁいいんだよ!という人へ。float...etc)しかメンバに持ってないとりあえず、これを抑えておけば大概はPODです。それでもPODじゃないデータ構造を定義してしまったら、逆にすごくね?と思うようにすると良いでしょう。blue_;};これもPOD。v;}};あと、おまけですがPODじゃない型のstaticメンバを持っていてもそのクラスのPOD性には影響ありません。