C++ †
MS による拡張 †
メモ †クラスを new させたくない場合 †コンストラクタを private (又は protected) にする。 class CantNewSample {
private:
CantNewSample() {}
}
スライスに気をつける †
class Foo
{
int x;
}
class Bar : Foo
{
int y;
}
void f()
{
Bar bar;
...
Foo foo = bar; // スライス
}
参照を使うのが手軽な解決。 Foo& foo = bar; 一時オブジェクトによるデストラクタの2回呼び出しに気をつける †
static int serial = 1;
class X
{
int n;
public:
X() { n = serial++; printf("%p X::X()\n", this); }
~X() { printf("%p X::~X() %d\n", this, n); }
};
void foo()
{
printf("foo()\n");
throw X();
}
void bar()
{
printf("bar() start \n");
try
{
printf("calling foo()\n");
foo();
}
catch (X& e)
{
printf("bar catch\n");
}
printf("bar() end\n");
}
bar() start calling foo() foo() 0012FCCC X::X() 0012FCCC X::~X() 1 ←本来の生存期間を抜けたので破壊 bar catch 0012FCC0 X::~X() 1 ←コピーされた一時オブジェクトが生存期間を抜けたので破壊 bar() end 一時オブジェクトは作られない場合もある。ただし、実装依存のはず。(最適化の1つ) 動いているからと言って安心してはならない。 static int serial = 1;
class X
{
int n;
public:
X() { n = serial++; printf("%p X()\n", this); }
~X() { printf("%p ~X() %d\n", this, n); }
};
X foo()
{
printf("foo()\n");
return X();
}
void bar()
{
printf("bar() start \n");
X x = foo();
printf("bar() end\n");
}
bar() start foo() 0012FE8C X::X() bar() end 0012FE8C X::~X() 1 |