2015-01-20 29 views
6

std::function örneğim, bir nesne örneğinin üye işlevine bağlıysa ve bu nesne örneği kapsam dışında kaldığında ve başka bir nedenle yok edilirse std::function nesnesim şimdi çağrılırsa başarısız olacak kötü bir işaretçi olarak kabul edilebilir?std :: nesnesinin işlevine ve nesnenin ömür boyu işlevine işlev

Örnek:

int main(int argc,const char* argv){ 
    type* instance = new type(); 
    std::function<foo(bar)> func = std::bind(type::func,instance); 
    delete instance; 
    func(0);//is this an invalid call 
} 

ne olacağını belirten standardında bir şey var mı? Benim önsezim, nesne artık mevcut olmadığı için atar ve istisnadır.

DÜZENLEME: Standart, ne olacağını belirtiyor mu?

Bu tanımlanmamış bir davranış?

DÜZENLEME 2:

#include <iostream> 
#include <functional> 
class foo{ 
public: 
    void bar(int i){ 
     std::cout<<i<<std::endl; 
    } 
}; 

int main(int argc, const char * argv[]) { 
    foo* bar = new foo(); 
    std::function<void(int)> f = std::bind(&foo::bar, bar,std::placeholders::_1); 
    delete bar; 
    f(0);//calling the dead objects function? Shouldn't this throw an exception? 

    return 0; 
} 

i, 0 bir çıkış değerini almak Bu kod çalıştırma;

+0

Yani, bu tanımlanmamış davranış veya what_? – moooeeeep

+0

Evet, bir işaretçi kullanıyorsunuz. Nesnenin kendisine bağlıysa, kopyalanan IIRC. – Columbo

+0

Bu tanımlanmamış bir davranış mı, yoksa ne olmasını bekleyebilirim ... Bir istisna, işe yarayacak ... başka bir şey. Bunu teorik bir bağlamda soruyorum. –

cevap

6

Ne olacağı tanımlanmamış bir davranıştır.

(instance->*(&type::func))(0); 

geçersiz işaretçi başvurusu kaldırıldığında instancedelete d olsaydı orada yapacağı gibi,: etkili arayacak func(0) çağırdığınızda böylece bind() çağrı, instance bir kopyasını içeren bazı nesne dönecektir

, tanımlanmamış bir davranıştır. Bir istisna atar (her ne kadar tanımlanmamış olsa da, kim bilir). Sesli arama bir yer tutucu kaçırdığınızı

Not: Bu olmadan

std::function<foo(bar)> func = 
    std::bind(type::func, instance, std::placeholders::_1); 
//         ^^^^^^^ here ^^^^^^^^^ 

, hatta silinmemiş örnekle func(0) diyemezsin. Daha iyi ne göstermek için örnek kod güncelleme

oluyor:

ekledi destructor ile
struct foo{ 
    int f; 
    ~foo() { f = 0; } 

    void bar(int i) { 
     std::cout << i+f << std::endl; 
    } 
}; 

, siz (f olarak) işaretçi kopyalama ve işaret edildi nesneyi kopyalama arasındaki farkı görebilirsiniz (içinde g):

foo* bar = new foo{42}; 
std::function<void(int)> f = std::bind(&foo::bar, bar, std::placeholders::_1); 
std::function<void(int)> g = std::bind(&foo::bar, *bar, std::placeholders::_1); 
f(100); // prints 142 
g(100); // prints 142 
delete bar; 
f(100); // prints 100 
g(100); // prints 142 still, because it has a copy of 
     // the object bar pointed to, rather than a copy 
     // of the pointer 
+0

@ Barry Kod sadece bir örnekti, ancak evet, yer tutucuya ihtiyaç duyulduğu için teşekkürler. Standartta bunun için başvurabileceğim bir yer var mı? –

+1

@AlexZywicki [bu eski soru] 'ya göz atın (http://stackoverflow.com/questions/4285895/where-exactly-does-c-standard-say-dereferencing-an-uninitialized-pointer-is-un) – Barry

+0

En azından POD işaretçi tipi durumunda davranış tanımsız olacaktır. 'Std :: function' tipi dahili olarak bir göstericiye gider mi? –