江添 C++ 本と本家ストラウストラップ本

プロになる Java』で Java の教科書的な書籍を取り上げたので、今度は C++ で。

当初、江添 C++ 本のみ取り上げようと思ったんだが、やっぱり(世にいう)ストラウストラップ本も必要かな?と思い、最初の版よりかなり内容変わってます。

ある程度実用的に C や C++ 使うんだったら、両方必要でしょう。

ワイの場合、C はまあまあ使えていたから、ここら辺から入ったが、C 未習の人は、この前に C の基礎をやっておいた方がいいでしょう。

江添 C++ 本

しっかり書かれた本ならなんでもいいと思うのだが、取り組みやすさを考えるならば『江添亮の C++ 入門』あたりがオススメ。

取り組みやすさ、というのは、この本のイントロが GitHub で公開されている、というのもその理由の一つ。

標準ライブララリを一つのヘッダファイルでまとめる話が第 2 章で出てくるが、こんなのいちいち打ち込むわけにもいかない。ここが該当箇所。

まあ、ならサンプルコード一覧つけてくれよ、と思わないでもないが。

これはケチをつけているわけではなく、Mac でこのコードを動かそうとしても動かない場合があるから。

‘cstdalign’ file not found エラーの回避方法

ワイの環境の場合、

‘cstdalign’ file not found

というエラーが出る。

なお、これを一番簡単に回避する方法は、以下のように cstdalign をコメントアウトして

#include <cstddef>
#include <limits>
#include <climits>
#include <cfloat>
#include <cstdint>
#include <cstdlib>
#include <new>
#include <typeinfo>
#include <exception>
#include <initializer_list>
//#include <cstdalign>
#include <stdexcept>
#include <cassert>
#include <cerrno>
#include <system_error>
#include <string>
#if __has_include(<string_view>)
# include <string_view>
#endif
#include <array>
#include <deque>
#include <forward_list>
#include <list>
#include <vector>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <iterator>
#include <algorithm>
#include <cfenv>
#include <random>
#include <numeric>
#include <cmath>
#include <iosfwd>
#include <iostream>
#include <ios>
#include <streambuf>
#include <istream>
#include <ostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#if __has_include(<filesystem>)
# include <filesystem>
#endif
#include <cstdio>
#include <cinttypes>
#include <regex>
#include <atomic>
#include <thread>
#include <mutex>
#include <shared_mutex>
#include <condition_variable>
#include <future>
using namespace std::literals ;

これをコンパイル。

g++ -std=c++17 -include all.h -o hello hello.cpp

などとする方法だろう。

こうすれば、mac でもとりあえずは動く。

 

しかし、この本、冒頭で「オススメ」とか書いちゃったが、今、読み返してみると、これは初学者向けの本ではないべ。

関数の説明でいきなりラムダ式

例えば、「関数」の説明でいきなりラムダ式が出てくるw

int main(){

    auto print = [](auto x){
        std::cout << x << "\n";
    };

    print("hello");
}

いや、手順通りにやれば確かに hello とは表示されるんですけどね。

あとで、これは本物の関数ではないと断っているんですが、お戯れ感がすごい。

実は class という言葉はなかなか出てこない

ほとんど struct で通しているw

というか今読み返している箇所では、今のところ class 出てきてねー(笑)。

C++ では関数も struct で扱えるからこれでも大した差は出ないんだが、

class のデフォルトでのアクセシビリティはデフォルトで private

struct のデフォルトでのアクセシビリティはデフォルトで public

という違いはある。
(『C++ における class と struct の違い』あたり参照)

実用的にはこれでも問題ないと思うが、多くの初学者が思う

「オブジェクト指向の特徴の一つ=カプセル化」

概念からすると違和感感じるかもしれない。

ここら辺はいわゆるストラウストラップ本の「C++ の言語機能の中核は、クラス(class)である」のような説明と一線を画す。
実際、ストラウストラップ本では、まず complex というクラス(名前から予想がつくように複素数を取り扱うクラス)の説明から入っている。

なお、たまに誤解している人もいるが struct でも継承はできます。

だから、「オブジェクト指向なので class というキーワードや使い方を期待している読者もいるかもしれないが、実用的には struct で代用できるので、ここでは struct で説明していく」と一言断っておけばいいんですよね。

また、Objective-C でも class は出てきません(@class というディレクティブはあるが、Java のようにわかりやすい形で class という単語が使われているわけではない)。NSObject を継承していて @property でメソッドが定義されているものがクラスだ、という風に理解されていると思います。

何をもってオブジェクト指向というのか?という宗教論争を引き起こしかねない話をここでする気はないので、まあ、そこら辺はスルーします。

テンプレートの説明はわかりやすい

逆にテンプレートのサンプルはわかりやすかったりする。

template <typename T>
T twice(T n){
    return n * 2;
}

int main(){
    twice(3);
    twice(3.14);
}

ああ、なるほど、こう書けば、いちいち型を気にする必要はありませんね。

プリプロセッサ

ここもわかりやすい。例えば

_cplusplus 具体的には C++17 ならば 201703L

あたりとか(40.8)。

なんというか書くのが疲れてきた(と思われる)後半に入って、わかりやすい記載になっていくのが興味深い。

ポインタ

著者が自信を持っていうだけあって、わかりやすくはあると思う。

ただ、これも初学者にはどうか?

スマートポインタ

ここもある程度慣れた人にとってはわかりやすいと思う。

スマートポインタ→生ポインタ (36章)あたりは、「へー、そういうことだったんですか!」といたく納得した。

 

(続く)

カテゴリーC++
クリックclose

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です