2016-03-30 24 views
3

Bu sorunun birçok yerde var olduğunu biliyorum. Ancak, örneklerin hiçbiri sorunumu çözmeme yardımcı olmadı.‘void (myClass :: *)() öğesini void (*)() dönüştürebilir()

yöntem işaretçisi yöntemini (bir sınıf içinde) oluşturmaya çalışıyorum, bu nedenle belirli koşullara göre sınıfın çeşitli yöntemlerinden birini ele alacaktır.

Statik bir işlev kullanmak için başarısız bir şekilde denedim (tahmin edersem nasıl yapılacağını anladım ...). Bazılarınızın bildiği gibi

myClass::myClass(int value){ 
    if(value > 0){ 
     send_msg = &methodA 
    } 
    else{ 
     send_msg = &methodB 
    } 
} 

ve hatalar:

error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say ‘&myClass::methodA’ [-fpermissive]

error: cannot convert ‘void (myClass::)(const string&) {aka void (myClass::)(const std::basic_string&)}’ to ‘void ()(const string&) {aka void ()(const std::basic_string&)}’ in assignment

herhangi bir yardım olacaktır

class myClass 
{ 
public: 
    myClass(int value); 

    void methodA(const string &msg); 
    void methodB(const string &msg); 

    void (*send_msg)(const string &msg); 
}; 

ve cpp: Burada

başlık dosyasıdır çok takdir edildi. Ben arayamam kodunu kullanmak çalışıyorum gibi şimdi

send_msg = &myClass::methodA; 

Ama:

void (myClass::*send_msg)(const string &msg); 

ve atama:

Düzenleme Jose sayesinde, bu derleme edilebilir işlev-işaretçisi:

this->myClass_instance.send_msg(line); //*****getting error***** 

zaman this, diğer sınıfın bir örneğidir. hatadır:

error: must use ‘.’ or ‘->’ to call pointer-to-member function in ‘((otherClass*)this)->otherClass::myClass_instance.myClass::send_msg (...)’, e.g. ‘(... ->* ((otherClass*)this)->otherClass::myClass_instance.myClass::send_msg) (...)’

+0

ammm .. o kullanarak daha kolay, daha okunaklı ve daha kısa olmaz 'std :: function' ve bir lambda işlevi? –

+0

@DavidHaim Bir örnek görmekten memnun olurum – Eli

+0

'send_msg' kullanmayı nasıl düşünüyorsunuz? – Barry

cevap

2

Benim demo: http://ideone.com/Vx4x88

Yap myClass:: ekleyerek sınıf yöntemine bir işaretçi send_msg. Eğer myClass:: ve

send_msg = &myClass::methodA; 
else 
    send_msg = &myClass::methodB; 

Düzenleme sonunda bir noktalı virgül ; eksik gibi

void (myClass::*send_msg)(const string &msg); 

Ayrıca, öyle görünüyor: yana

senin sınıf dışından aramak nasıl talep senin açıklama:

( )
myClass * p = new myClass(1); 
(p->*p->send_msg)("hi"); 
+0

@Jose Teşekkürler. Derleme gibi görünüyor, ancak hatayı alıyorum: ope -> ’temel işleneni, dışardan çağırmak için işaretleme yaparken‘ myClass’' işaretçisi değil. – Eli

+0

@Eli Peki nasıl aradınız? – songyuanyao

+0

Üzgünüm, bu cookiede alışkanlık yaratmıyor .. – Eli

2

void (*send_msg)(const string &msg);, statik olmayan üye işlevi değil, serbest işlev veya statik üye işlevi için işaretçinin bildirimidir.

void (myClass::*send_msg)(const string &msg); 

LIVE1

Yoksa statik üye işlevi olmasını işlevleri yapabilir: Sen isteyebilirsiniz

static void methodA(const string &msg); 
static void methodB(const string &msg); 
1 derleme hatası için

LIVE2

, adı nitelemek gerekir adresi alınırken statik olmayan üye işlevinin (yalnızca 1. çözüm için):

myClass::myClass(int value){ 
    if(value > 0){ 
     send_msg = &myClass::methodA; 
        ~~~~~~~~~ 
    } 
    else{ 
     send_msg = &myClass::methodB; 
        ~~~~~~~~~ 
    } 
} 
2

ayrıca işlevi çağırmak için std::function

#include <functional> 

class myClass 
{ 
public: 
    myClass(int value){ 
    if(value > 0){ 
     send_msg = [this](const std::string& str){ methodA(str); }; 
    } 
    else{ 
     send_msg = [this](const std::string& str){ methodB(str); }; 
    } 
    } 

    void methodA(const string &msg); 
    void methodB(const string &msg); 

    std::function<void(const string &msg)> send_msg; 
}; 

kullanabilirsiniz, sadece () kullanın:

myClass obj(10); 
obj.send_msg("hi there"); 
+0

Ama bence soru üye fonksiyon göstericileri hakkındaydı ve bunları nasıl yapacağını bilmek çok önemli ve std :: function olan en kolay yol için gitme. Temel olarak, bellek ayırma, sanal arama ve hatta boş bir std :: function nesnesi gibi çok fazla genel yüke sahip olduğu için genellikle çok büyüktür (MSVC2015'te en az 40 bayt). – Jts

+0

Asgari genel giderler ile gitmeye eğilimliyim. Kontrol etmedi, ama umarım Jose çözümü daha iyi olur. Her iki cevap için +1. – Eli

+0

Üye fonksiyonlarına% 100 özdeğer denkliği olmadığını kabul ediyorum, alternatif bir yaklaşım göstermek istedim. her neyse, eksiler gerçek olmasına rağmen ciddiye alınmalıdır, artılar, 'std :: function' null veya sarkan olamayacağından daha kolay ve daha güvenlidir. boş bir 'std :: function' çağrıldığında bir istisna atar, nulled/sarkan üye fonksiyonu çağrılırken UB –