自分メモを公開(c#やJavaの経験がある人向け)
自分は複数の環境でコードを書いている。実際, 挙動の違いがあるが面倒なので, できるだけg++でコンパイルした(__cplusplusは 201402L)結果を書くようにする。
constructorとdestructor
- メモリの確保時にconstructorが呼ばれ, メモリの解放時にdestructorが呼ばれる
シンボル
- 宣言
- (型名*) : pointer declare
- (型名&): reference declare
- (宣言済の)変数
- (*変数) : address -> value
- (&変数): value -> address
自動変数によるインスタンス
Color c;
- メモリはstack領域に確保される
- 変数宣言時にメモリが確保される
-
Color c = Color();
と書くと初期化していないメンバ変数がデフォルト値により初期化される(詳しくは知らない) - (Automatic storage duration objects)
newによるインスタンス
Color*c; c = new Color();
- ポインタ型
- メモリはheap領域に確保
- (Dynamic storage duration objects)
stack over flow
- stack領域を使いすぎるとstack over flowが起きる。メソッド内で使い終わる等でなければnewを使うことになる
メモリリーク(new/delete)
- newを使った変数は, 不要になったときにdeleteする必要がある
- (mallocを使わなければ, メモリリークはnewを使ったときだけのはず...)
- OK
-
Color* c = new Color(); delete c;
-
- ダメ(Leak)
-
Color* c = new Color(); c = 0;
void main(){ Color* c = new Color ; }
Color* c = new Color(); c = new Color(); delete c;
-
Array
arrayはstack領域(連続した領域)に作られる
a[3]
は*(a + 3)
のsyntactic sugararrayのコピーはmemcpyかloopを使う
-
int* d = new int[5];
のような書き方もある- この場合はheap領域に確保される(deleteもいる)
pointerとarrayは同じようなふるまいになる
int a = 3;
int* b = &a;
cout << b << endl; // address
cout << *b << endl; // 3
int* c = b;
int x[] = {3,4}; // 初期化
cout << x << endl; // address
cout << *x << endl; // 3(先頭の値)
int* z = x;
struct
- class はデフォルトのアクセシビリティがprivate
- structはデフォルトのアクセシビリティがpublic
-
struct Table{int x} t0;
// structの宣言と同時にインスタンスを作る -
struct {int x;} t1;
// 匿名のインスタンスが作れる
struct person{ int x; int y;};
person a {0, 123}; // 初期化
person b = {}; // すべての値を0で初期化
static
class Test{public: static int x;};
int Test::x = 123; // 必須(↑では初期化できない)
int main(){cout << Test::x; /*123*/}
初期化
-
int x(3);
はint x = 3;
と同じ - global変数は初期化していないとデフォルト値が入る
- local変数やnewによるインスタンスのメンバ変数はコンパイラ依存の変な値になる
class Test
{
public:
int x; int y;
Test(): x(4),y(9) {} // x, yの初期化
};
cast
- dynamic_cast, static_cast, reinterpret_cast, const_castがある
- c型cast
(int) x
も使える. (非推奨らしい) - あまり詳しくない
header(クラスの例)
a.h
class Foo
{
public:
void test();
}; // class構文の終わりにはセミコロンがいる
a.cpp
#include "a.h"
#include <iostream>
void Foo::test(){std::cout << 123;} // メソッドの実装の終わりにはセミコロンがいらない
int main()
{
Foo* foo = new Foo();
foo->test(); // (*foo).test()のsyntactic sugar
return 0;
}
- メソッドの定義の部分で実装もできるし, headerとファイルを分けずに実装もできる
- 1行メソッド的なのはheaderで実装したりする
文字(single character)
char c = 'a'
文字(string literal)
"abc"
はstring literal
const char* c0 = "abc"; // ok;
char c1[] = "abc"; // ok;
char* c2 = "abc"; // g++(201402L)環境ではコンパイルエラー
const char* const c3 = "abc"; // 定数
const char* c4 = "ab" "cd"; // 文字の結合
switch
- fallthrough する
- (たぶん)最後でないcaseの中でlocal変数を定義する場合は, {}でくくる必要がある
他
-
class A{friend class B;};
クラスBはAのprivateにアクセスできる - c#などの
interface
はない-
void virtual foo()=0;
のように書くとinterfaceのような働きをする
-
- メソッドの中で, classを定義できたりenumを定義できたりできる
-
extern
他のファイルで定義したglobal変数などをあるファイルで使うときに