誰にも見えないブログ

雑なメモ。まとまってない文章等

今日のC++:auto,nullptr,enum class等

無謀にもStroustrupの本で勉強します。

冒頭~「2.4.1分割コンパイル」まで読みました。 検証コードはgithubにちょくちょく書いてます。

github.com

main関数

すべてのC++プログラムはmain()という名前の広域関数をひとつだけ持たなければならない。main()を実行することによって、プログラムの処理が始まる。main()が返却する値の型はintである。(中略)mainが非ゼロを返却するのは、処理に失敗したことを伝えるときだ。

  • こういうの大事

helloworld

#include<iostream>

int main(){
    std::cout << "Hello, World!\n";
}
  • std::coutcoutが標準ライブラリの名前空間stdに存在することを示す

初期化=,{}どっち使う?

  • {}を使う方法は縮小変換という概念を避けることができるらしい

=形式は、Cの時代から伝統的に用いられてきたが、どれを使うか迷うくらいならば、並びを{}で囲む形式のほうを使うとよい

int i1 = 7.2;//i1は7になる(驚いたかな?)
int i2 {7.2};//エラー:浮動小数点から整数への変換
int i3 = {7.2};//エラー:浮動小数点から整数への変換(=は省略可)
  • 確かにエラーが出た

というわけで言語設計者的には{}推しのようです。

autoキーワード

  • autoキーワードで型宣言を省略できる(varriable型ではなさそう)
    auto i2 = 7;
    std::cout << i2 << std::endl;

auto関数はどうやらC++11で入った機能のようだ。

https://cpprefjp.github.io/lang/cpp11/auto.html

for-each構文にautoが使えるのはかっこいい

    for (auto x:v2){
        std::cout << x << std::endl;
    }
  • for(auto& x: v2){とすることでv2の内容をxに代入することなく、参照することができる

imutableな修飾子

  • const:不変であることを示す
  • constexpr:コンパイル時に評価されることを示す

note:constの方がきつい感じか。

定数式(constantexpression)の中でも利用できる関数、すなわち、コンパイラによって評価されることになる式の中で利用される関数は、constexprとして定義しなければならない。

constexpr double square(doublex){return x*x;}

  • うーん特にconstexprにしなくても警告、エラーはでなかったが。
void const_test(){
    const int i=7;
    //i++; エラー
    const int i2 = square(6);
    std::cout << i2 << std::endl;
}
int square(int v){
    return v*v;
}
  • constexprは定数式以外からも利用できる

pointer

ほぼCと同じ

  • *x reference
  • &x dereference
  • 有効なオブジェクトではない場合はpointerにnullptrを代入する
    • 古いコードでは0NULLが用いられていた。
      • バグの温床

enum class

  • enumと書くことで、C言語と同じく、intと比較可能なenumを作成することができる
    • 本中には
    • ちょっと微妙な仕様→C++11enum classが追加された。
  • enum class

  • memo:enum(enum classではない)にはint型の値を代入できそうな雰囲気があるが、自分が試した範囲ではそのようなことはできなかった

enumclass宣言によって、個々の型を異なるものとしておけば、定数の誤用などの事故が防げる。たとえば、Traffic_lightの値とColorの値は、混用できなくなる:

Colorx=red;//エラー:一体どこのred?
Colory=Traffic_light::red;//エラー:このredはColorではない
Colorz=Color::red;//OK

同様に、Colorと整数値の混用もできない:

inti=Color::red;//エラー:Color::redはintではない
Colorc=2;//エラー:2はColorではない
  • 末尾のコードはまるでennum classで解消したenumの変な挙動、のように紹介されていたが、enum型の変数にint型を入れることはできなかった。
enum class Color{red,blue,green};
enum Week {sun,man,tus,wed,the,fri,sat};

void enum_test(){
    Color col = Color::red;
    //Color col2 = 0;//error
    /**
     * enum classにint型の代入はできない。以下のエラーメッセージがでる。
     * Cannot initialize a variable of type 'Color' with an rvalue of type 'int'
     */

    //if(col==0){}
    /**
     * enum classはintと比較できない。
     * Cannot initialize a variable of type 'Color' with an rvalue of type 'int'
     */
    Week week = sun;
    if (week == 0){
        /**
         * enumとintの比較は可能。
         */
        std::cout << "Week:Sun is 0!!!" << std::endl;
    }
    //week = 1;
    /**
     * enumに対してintは比較はできるが、代入は無理みたいだ。
     * assigning to 'Week' from incompatible type 'int'
     */
}

  • dereferenceの"参照外し"という訳は個人的にしっくりこない。(まぁ好みの問題です)
    • pointer型から実際にアドレスがさしてるオブジェクト得る、というニュアンスがわかりにくいと思う。
    • これは個人的な好みだけど、日本語に訳しにくい単語はそのまま英語で載せていいと思う。(併記する訳者もいる)
  • CLionでプロジェクト名を変更するときはフォルダの名前変更に加えて.ideaディレクトリの.nameファイルの変更が必要

プログラミング言語C++ 第4版

プログラミング言語C++ 第4版