Bu bir derleyici hatasıyla sonuçlanmaz, ancak bir çalışma zamanı hatasıyla sonuçlanır. Yanlış bir zamanı ölçmek yerine, kabul edilebilir bir istisna elde edersiniz.
Korumak istediğiniz herhangi bir kurucu set(guard), çağrılan varsayılan bir argümana ihtiyaç duyar .
struct Guard {
Guard()
:guardflagp()
{ }
~Guard() {
assert(guardflagp && "Forgot to call guard?");
*guardflagp = 0;
}
void *set(Guard const *&guardflag) {
if(guardflagp) {
*guardflagp = 0;
}
guardflagp = &guardflag;
*guardflagp = this;
}
private:
Guard const **guardflagp;
};
class Foo {
public:
Foo(const char *arg1, Guard &&g = Guard())
:guard()
{ g.set(guard); }
~Foo() {
assert(!guard && "A Foo object cannot be temporary!");
}
private:
mutable Guard const *guard;
};
Özellikler şunlardır:
Foo f() {
// OK (no temporary)
Foo f1("hello");
// may throw (may introduce a temporary on behalf of the compiler)
Foo f2 = "hello";
// may throw (introduces a temporary that may be optimized away
Foo f3 = Foo("hello");
// OK (no temporary)
Foo f4{"hello"};
// OK (no temporary)
Foo f = { "hello" };
// always throws
Foo("hello");
// OK (normal copy)
return f;
// may throw (may introduce a temporary on behalf of the compiler)
return "hello";
// OK (initialized temporary lives longer than its initializers)
return { "hello" };
}
int main() {
// OK (it's f that created the temporary in its body)
f();
// OK (normal copy)
Foo g1(f());
// OK (normal copy)
Foo g2 = f();
}
Durumunda f2, f3ve dönüşü "hello"istediği olmayabilir. Fırlatmayı önlemek için guard, kopyanın kaynağı yerine şimdi koruma ayarını sıfırlayarak kopyanın kaynağının geçici olmasına izin verebilirsiniz . Şimdi, yukarıdaki işaretçileri neden kullandığımızı da anlıyorsunuz - esnek olmamızı sağlıyor.
class Foo {
public:
Foo(const char *arg1, Guard &&g = Guard())
:guard()
{ g.set(guard); }
Foo(Foo &&other)
:guard(other.guard)
{
if(guard) {
guard->set(guard);
}
}
Foo(const Foo& other)
:guard(other.guard)
{
if(guard) {
guard->set(guard);
}
}
~Foo() {
assert(!guard && "A Foo object cannot be temporary!");
}
private:
mutable Guard const *guard;
};
İçin karakteristikleri f2, f3ve için return "hello"her zaman şimdi // OK.