C++ の覚え書き

最終更新  2024.04.01


◆◆ ファイル入出力 ◆◆


#include <fstream>

入力

ifstream infs

infs.open("fname");
if ( infs.is_open() == 0 ) errmsg("cannot open\n");

ch = infs.get();
if ( ch == NULL ) break;

infs.getline(str,maxlen);
if ( infs.eof() == true ) break;

infs >> nx >> ny;

infs.close();

       --------------------

出力

ofstream outfs;

outfs.open("fname");
if ( outfs.is_open() == 0 ) errmsg("cannot open\n");

outfs.put(ch);
outfs << "string" << a << endl;

outfs.close();

◆◆ rewind ◆◆


fp.clear();   <-- これを怠ると EOF になっているとき、先頭に戻らない
fp.seekg(0);


◆◆ 参照 ◆◆


sub(int& a)
{
    a = 2;
}


int a;
sub(a);


◆◆ 複素数 ◆◆


#include <complex>
using namespace std;
main()
{
    complex<double> a;
    a = complex<double>(2,3);
    printf("%f %f\n",a.real(),a.imag());
}


◆◆ string クラス ◆◆


string str,str2,str3;

str  = "yabu";
str2 = "tetsuro";

str3 = str + str2;

printf("%s",str3.c_str());


◆◆ min, max ◆◆


a = min(b,c)  ---->  a = ?


◆◆ コンストラクタ ◆◆


コンストラクタを作成しない場合は、デフォルトの
引数無しコンストラクタがコンパイラによって作成される。

コンストラクタを1つでも作成した場合は、
それ以外のコンストラクタは作成されない。

例えば、引数を1つ持つコンストラクタを宣言したとき、
引数無しコンストラクタは作成されない。


◆◆ コンストラクタが呼ばれる順序 ◆◆


先祖のコンストラクタから順番に呼ばれる。
デフォルトでは先祖の引数なしコンストラクタが呼ばれる。
先祖のコンストラクタを選びたい場合は、以下のように記述する。

以下のサンプルプログラムを変更して理解すること。

#include <stdio.h>

class senzo {
public:
    senzo();
    senzo(int input);
private:
};

senzo::senzo()
{
    printf("senzo : empty constractor\n");
}

senzo::senzo(int input)
{
    printf("senzo : argument constractor\n");
}

class musuko : public senzo{
public:
    musuko();
    musuko(int input);
private:
};

musuko::musuko() : senzo(1) // <-- これを省略すると senzo() を呼ぶ
{
    printf("musuko : empty constractor\n");
}

musuko::musuko(int input) : senzo(input) // <-- これを省略すると senzo() を呼ぶ
{
    printf("musuko : argument constractor\n");
}

main()
{
    musuko a;

    musuko *b;
    b = new musuko(3);
}



◆◆ 仮想関数 virtual ◆◆


先祖クラス shape で rect, circle などを統一的に扱う方法。
以下のサンプルプログラムを参照。

#include <stdio.h>

class senzo {
public:
    virtual void func();  // <--- この virtual がないと、先祖の func を読んでしまう
private:
};

void senzo::func()
{
    printf("senzo : func()\n");
}

//---------------------

class musuko : public senzo{
public:
    void func();
private:
};

void musuko::func()
{
    printf("musuko : func()\n");
}

main()
{
    senzo  *s;
    musuko  a;

    s = &a;     // 先祖のポインタを使う

    s->func();  // どちらの func を呼ぶ?
}


◆◆ コピーコンストラクタ ◆◆


サブルーチンにオブジェクトを値渡しするとき、
戻り値に静的なオブジェクトを指定する場合、
コピーコンストラクタが呼ばれる。

クラス内の静的な変数は問題ないが、コンストラクタにおいて
malloc した変数領域がある場合、デフォルトのコピーコンストラクタ
ではポインタがコピーされる。それでは、サブルーチンから
戻った場合などのときにデストラクタが呼ばれた際に、
malloc した領域が free されてしまい、問題が生じる。

このため、コピーコンストラクタを自前で書き、その中で
malloc して領域を確保し、領域をコピーする必要がある。

サブルーチンへの値渡しや値戻しを禁止する場合は、
コピーコンストラクタをプライベートにする。


◆◆ クラスへのポインタ ◆◆


次の表現は等価である。

c_ptr = &c_obj

c_ptr->member;
(*c_ptr).member;

サンプルプログラム

#include <stdio.h>

class myclass
{
public:
    int aa;
};

int main()
{
    myclass ins;
    myclass *list[3];

    list[0] = &ins;

    ins.aa = 2;

    printf("%d\n",list[0]->aa);
    printf("%d\n",(*list[0]).aa);

}

◆◆ クラスの記述方法 ◆◆


.h の中に全て書く場合は以下のように書く

class YKinect{
    int i;

    func1(){

    }
};

.cpp と .h に分けて書く場合は以下のように書く

.h

class YKinect{
    int i;
    func1();
};

.cpp

YKinect::func1(){

}


◆◆ 構造体の初期化 2013.1.8 ◆◆


struct_name variable_name = { 0 };

全ての要素に 0 が入る。


◆◆ 重複インクルードを避ける方法 ◆◆


.h に以下のように書く

#ifndef __label__
#define __label__

   インクルードファイルの内容

#endif


◆◆ デフォルトの引数 ◆◆


void func(int a, int b = 3){
    printf("a = %d    b = %d\n",a,b);
}

main(){
    func(1,2);
    func(1);
}

◆◆ 時刻の取得 ◆◆


#include <Windows.h>

    SYSTEMTIME t;
    GetLocalTime(&t);
    prev_time = t.wHour * 3600 + t.wMinute * 60 + t.wSecond;
    a = t.wMilliseconds;