2016-04-20 10 views
2

Ich habe den folgenden Code: eine Schablonenklasse, die von einer Schnittstelle abgeleitet wird, benötigt eine statische lokale Funktion. Ich habe es als Freund erklärt; Die Funktion kann jedoch die privaten/geschützten Mitglieder nicht "innerhalb dieses Kontexts" aufrufen.Wie man Freund eine statische locale Funktion erklärt

Wie legen Sie diese statische Gebietsschema-Funktion als Freund richtig fest?

Ich spezifiziere meine Klasse als Vorlage weil ich deswegen keine Inline-Friend-Funktion verwenden kann (der Compiler sagt, dass meine Funktion neu definiert ist).

Außerdem kann ich die Interface-Klasse nicht ändern.

Dies ist der Code:

class Interface 
{ 
    protected: 
     virtual void virt(void) = 0; 
}; 

static void bar(Interface *b); 

template<class T> 
class Foo : public Interface 
{ 
    // How to properly say the local function bar is friend ? 
    friend void bar(Interface *b); 

     T val; 

    public: 
     void virt(void) 
     { 
     } 

     void func(void) 
     { 
      bar(this); 
     } 
}; 

static void bar(Interface *b) 
{ 
    b->virt(); // Error: virt() is protected. 
} 

int  main(void) 
{ 
    Foo<int> foo; 

    foo.func(); 
    return 0; 
} 

Antwort

1

Wenn Sie nicht die Interface Klasse ändern, dann können Sie einfach eine Zwischenklasse einführen, um das geschützte Mitglied zu erhalten:

class Interface { 
protected: 
    virtual void virt(void) = 0; 
}; 

class Interface2 : public Interface { 
public: 
    virtual void virt(void) = 0; 

}; 

static void bar(Interface2 *b); 

template<class T> 
class Foo : public Interface2 { 
    // How to properly say the local function bar is friend ? 
    friend void bar(Interface2 *b); 

    T val; 

public: 
    void virt(void) 
    { 
    } 

    void func(void) 
    { 
     bar(this); 
    } 
}; 

static void bar(Interface2 *b) 
{ 
    b->virt(); // Error: virt() is protected. 
} 

int  main(void) 
{ 
    Foo<int> foo; 

    foo.func(); 
    return 0; 
} 
3

bar ist der Freund von Foo, aber nicht Freund von Interface. Und es gibt keine Notwendigkeit, bar als Freund von Foo zu deklarieren, weil es nur die geschützte Elementfunktion auf Interface aufruft. Sie können es als Freund von Interface deklarieren.

class Interface; 
static void bar(Interface *b); 

class Interface 
{ 
    friend void bar(Interface *b); 
    protected: 
     virtual void virt(void) = 0; 
}; 
+0

Vielen Dank für Ihre Erklärung, ich sehe ich den Freund Konzept falsch verstanden. Allerdings akzeptierte ich die flatmouse Antwort, weil er mir eine Lösung für das Problem gab. – Boiethios

1

Für

static void bar(Interface *b) 
{ 
    b->virt(); // Error: virt() is protected. 
} 

arbeiten Sie bar ein friend von Interface machen müssen. Ob es sich um eine friend der abgeleiteten Klassen handelt oder nicht, macht keinen Unterschied.

Verwandte Themen