C++ステップアップにむけて 段階を作ってみた

ソースコードはイメージでコンパイル出来る気はしません。イメージです

TL;DR

なぜかうちは このご時世でC++案件ばかり頂きます
ありがたいことです
ゲーム案件以外にも、boost.asioの高速サーバ案件、boost.asio指定で HTTPSのクローリング、EmscriptenでAsm.jsに
など

新人をもっとC++教育したいので、教育メソッドを作ろうとしている最中ですが
まずは、自分がどの程度理解して、次は何を勉強すべきかが明確になるように
段階を作ってみようという試み

Cゲンガー (Better C)

特徴

古き良き時代のC言語である
彼らの特徴は、たいていの場合最初に

betterC
#include<stdio.h>
int main(int argc, char *argv[]){
    return(0);
}

などと書くだろう。
C++はC言語と互換性があるため、C言語ソースをそのままコンパイル出来るし、C言語よりコンパイルエラーも厳密なので
コンパイラを変えるだけでもメリットがある

また、彼らの特徴は、戻り値を intにすることが多い
ただし 0が失敗1が成功だったり、負の値は失敗だったり、0が成功で1以降はエラーだったり
関数ごとに戻り値のエラー確認が違うことが多いので気を付けなければならない
例外もないため、すべてのエラー処理はエラーコードで判断するので重要である

また、彼らは何でも void * にキャストを行う 強引なキャストを行う
これは当然 重大なバグを生むことになる

そして彼らは 生ポインターが大好きで malloc、freeを多用する
コンストラクタもデストラクタも無いので
hoge_init() 関数と hoge_free() 関数を作り、外から必ず呼んでもらえる事を前提にする
そのため不具合の大半がメモリリークということになる

ステップアップには

下記のstaticおじさんを経由しないように、オブジェクト指向を勉強しよう。
JavaでもC#でもいいし、C++でいきなりオブジェクト指向やってもいい
くれぐれも、classがよくわからないので メンバをstaticにして満足してはいけない

staticおじさん(C with namespace)

特徴

なぜか時々みかけるのだが、classをインスタンス化せず、全部クラスメソッドで使う人がいる
おそらく、オブジェクト指向を理解していないが まわりの書き方を彼らなりに真似した結果なんだろうが。。。
コンストラクタとデストラクタだけは使っている人もいるが、独自にinitとfreeメソッドを実装する人が多い

当然 staticメソッドなので、複数の処理を行うには外部で構造体を管理し、それを渡すという、オブジェクト指向の根本の データとメソッドを一緒にすることが出来ていない

アクセス制限も気にしていないのか、全部publicである事も多い

static
#include<stdio.h>

struct DISPLAY_DATA{
  char *name;
};

class hoge{
public:
  static void init_data( DISPLAY_DATA *data, char *name ){
    data->name = malloc(strlen(name)+1);
    strcpy(data->name, name);
    data->name[strlen(name)] = 0;
  }
  static void free_data( DISPLAY_DATA *data ){
    free(data->name);
  }
  static void print(DISPLAY_DATA *data){
      printf("name=%s\n", data->name);
  }
};

int main(){
  DISPLAY_DATA data;

  hoge::init_data(data, "らぁら");
  hoge::print(data);
  hoge::free_data(data);
  return(0);
}

実はこれ、クラスをネームスペースとして利用しているだけなんですよ!
とても禍々しいので classキーワードを namespaceにして C言語として書き直していただきたい

ステップアップには

完全に考えている事が間違えているので
ちゃんとオブジェクト指向を理解しましょう
C++が難しければ JavaやC#の方が 多重継承や仮想関数テーブルなどを考えなくても良いので難易度低いです
VisualBasicでもいいです
もし上記のコードを書いているならいますぐ 得意のC言語スタイルで書きましょう
その方が100倍良いです

オブジェクト指向(C with classes)

特徴

大半のC++の人はここだと思う。あるいはこの1歩先のSTL
ので、このレベルで十分仕事出来ます
10年前とかだとMFCというフレームワークがあり、このレベルの人用で大量に仕事がありました
ただ、MFCはほぼ死に、MicrosoftもATLというテンプレートライブラリやSTL推奨してきているので
ぜひ ステップアップしてください

といっても、このステップはとても知識の幅が広くなるので、全部を理解するのは至難です
継承、派生、多重継承、仮想関数テーブル、ランタイム型などなど・・・
また 例外処理も入ってきます

例えば先ほどのは

class
#include<stdio.h>

class hoge{
private:
  char *name;
public:
  hoge(char *name ){
    this->name = new char[strlen(name)+1];
    strcpy(this.name, name);
    this.name[strlen(name)] = 0;
  }
  virtual ~hoge(){
    delete[] name;
  }
  void print(){
      printf("name=%s\n", name);
  }
};

int main(){
  hoge h("みれぃ"); 
  h.print();
  return(0);
}

データとメソッドが一緒になり、オブジェクト指向として正しいものになったと思う
ここで少し くすぐったいと思う人は次ステップ以降の住民だろう
STLを使うともっときれいに書けるからね

ステップアップには

とりあえず このランクで仕事は出来るが、絶対にSTLが使えると便利なので
よく使うものから 1個ずつSTLを覚えていくといい
まずは printfをcoutにして、string、vector等のコンテナを使い
list、map、queueなどコンテナ知識を増やし iteratorとalgorithmを使っていく
テンプレートを使ったジェネリックプログラミングは最初は慣れないかもしれないが
せめて使うことが出来るようにしたい

STL (C with STL)

特徴

自分でTemplateを使ったライブラリはあまり書かないが
STLでジェネリックプログラミングができるレベル
正直 ここまで行けば ほとんどの仕事はこなせるし
C++プログラマの大多数は この段階までである

このランクになるとおそらく stdio.hやstdlib.h等の旧スタイルのヘッダに違和感が出てきているはず
最初の段階では生ポインタに関して違和感がないかもしれないが
STLを使っていくうちに 生ポインタの限界をしり スマートポインタを使うようになるはず
何故なら STLコンテナに生ポインタを突っ込むと、解放されないという経験をするはずだからだ

STLもC++11、C++14と扱う範囲が増え(boostからの移植)
知識量も必要になってきたが
よく使うものは限られているので、使うものから覚えていけばよい

先ほどのコードは例えば

stl
#include<iostream>

using namespace std;
class hoge{
private:
  string name_;
public:
  hoge(const string &name ): name_(name){}
  void print(){
    cout << name << endl;
  }
};

int main(){
  hoge h(string("みれぃ")); 
  h.print();
  return(0);
}

非常に しっくりとくるコードになってきた

ステップアップには

Boostかな。
スマートポインタ、thread、hashコンテナ、関数型プログラミング
など、Boostから標準ライブラリに移植されたものも多い
ファイル入出力や 非同期通信、3DやGPU等、STLには無い数多くのライブラリが揃っているので
使えるようになると非常に幅が広くなる

Boost (C with Boost)

概要

STLでたいていの機能がそろっているが、それでも足らない事がある
そんな時にboostライブラリを使うことがある
といっても 機能が多く、少し癖の強いライブラリが多いもののSTLが使えれば扱うことが出来る

ステップアップ

Boostライブラリの中でも普段使わないものの使い方を覚え
必要になったらいつでも使えるように知識を広めたり
Boostに足りないものは 自分でテンプレートライブラリを書く事である

ジェネリック(C with Templates)

概要

世の中にC++のライブラリは複数ある。特にSTLとBoostは多くの優れた技術者の手が入り
機能も速度も安定性も優れているが
それだけでは物足りず、自分でTemplateライブラリを書くことがある
例えば 独自のコンテナを実装したり、メモリアロケータを実装することもあるだろう
このレベルに来ればあとは自分で上達の道を見つけるしかないと思う
自分の行き先を考えて、知識をひろめよう

ステップアップ

世界の英知が詰め込まれている STLやBoostのコードを見て勉強をする
関数型プログラミングや メタプログラミングなどを勉強する
そして最後は、C++の規格を読む事になると思う