日記

ただの日記

C言語->C++で見つかる不思議な文法

C++を始めたときにJavaともC言語とも似つかないよな文法があって困ったので書く。 参考サイトを見ながらムムっと感じたところをメモっているので、網羅性はない。

参照渡し

Javaにもあるけどね

// 参照渡し
void set10 (int &x) {
  x = 10;
}

//ポインタ渡し
void set20 (int* x) {
  *x = 20;
}

int main() {
  int i = 0;
  cout << i << endl; //0
  set10(i);
  cout << i << endl; //10
  set20(&i);
  cout << i << endl; //20
  return 0;
}

変数の初期化

class Student {
public:
  Student();
private:
  int x, y;
}

Student::Student() : x(0), y(0) {
    // これだけでx, yが初期化される
}

変数の初期化(スタック上)

コンストラクタに引数を含むオブジェクトをスタック上に宣言する場合にどうすればいいのだろうと思ったが、変な宣言法がある。

class Student {
    int x, y;
public:
    inline Student(int x, int y) {
        this->x = x;
        this->y = y;
    }

    inline int getx() {
        return x;
    }

    inline int gety() {
        return y;
    }
};

int main() {
    Student student(100, 200); //宣言と同時に括弧で引数を入れることができる。
    cout << student.getx() << endl;
    cout << student.gety() << endl;

    system("pause");
    return 0;
}

配列の開放

int *p = new int[10];
...
delete[] p;

constによる宣言

通常の変数とポインタで別れる。ややこしい。

//通常
const int v = 30;
//ポインタ
const int* a = &b; // ポインタ先の書き換え負荷(ポインタの変更はできる)
int* const a = &b; //ポインタの書き換え制限(ポインタ先の変更はできる)
const int* const a = &b //両方不可

const関数

関数のあとにconstがついてる某。宣言時のconstはパット見でわかるけど、 関数の引数のあとについてると焦る。

この関数によってメンバ変数を変更しないという意味。
正確にはthisポインタを制約する。(参考↓)

class Student {
int id = 10;
public:
  inline void set(int x) const {
    id = x; // これができない
  }
};

テンプレート関数

template <typename T>
T add(T x, T y) {
  return x + y;
}

int main() {
  cout << add<int>(1,1) << endl;
  cout << add<double>(3.0, 5.5) << endl;
  cout << add<string>("hello ", "world") << endl;
  
  // 型が一致していれば省略可
  cout << add(1,2) << endl;
  cout << add(1.1, 3,3) << endl;
  
  //型が一致していなければビルドエラー
  cout << add(1.0, 1) << endl;
  
  return 0;
}

テンプレートクラス

クラスに関してもクラス宣言の前にtemplateを宣言すると型を変更できるようになる。

template <typename T>
class Moimoi {
private:
    T n1;
    T n2;
public:
    inline void set(const T n1, const T n2) {
        this->n1 = n1;
        this->n2 = n2;
    }

    inline T add() const {
        return n1 + n2;
    }
};

int main() {
    Moimoi<int>* moi = new Moimoi<int>;
    car->set(10, 20);
    cout << car->add() << endl;
    delete car;

    return 0;
}

親クラス(スーパークラス)のコンストラクタの呼び出し

Javaならsuper()で一発だが、C++だとちょっと奇妙な書き方

// スーパークラス
class Animal {
public:
    Animal(int age);
protected:
    int age;
};

// サブクラス
class Dog : public Animal {
public:
    Dog(int age) : Animal(age) {
        //コンストラクタの中身
        //ここが呼ばれる前に先にスーパークラスのコンストラクタが呼ばれる
    }
};

その他

リンク集 - 相互参照 - クラス間の相互参照

参考サイト