2016-09-14 1 views
0

Für die Hausaufgaben, ich bin eine Skelett-Klasse zur Verfügung gestellt und aufgefordert, Funktionen aus dem Header in der Quelldatei zu implementieren. Ich bin nicht erlaubt, den Header zu ändern, da es nicht nur die Implementierungsdatei ist.Elementfunktion in Implementierungsdatei hinzufügen

Es gibt jedoch eine Funktion, die ich wirklich der Klasse hinzufügen möchte (die operator() -Funktion). Wie kann ich es als Teil der Klasse deklarieren, ohne den Header zu ändern?

Ich kann keine Friend-Funktion hinzufügen (erfordert die Änderung der Klassendefinition in der Kopfzeile). Ich kann es nicht einfach an der Spitze der Quelle implementieren (Out-of-Line-Definition stimmt nicht überein ...). Ich kann die Klasse nicht neu deklarieren (Neudefinition der Klasse).

Ist das überhaupt möglich? Dadurch kann ich den Funktionskörper an 4 verschiedenen Stellen im Code kopieren.

FYI, es ist ein Accessor für eine kreisförmige, doppelt verknüpfte Liste. Der Operator [] wird verwendet, um auf Listenelementelemente zuzugreifen, und ich benötige einen Zugriffsmechanismus, der stattdessen den Listenelementzeiger zurückgibt. Als Referenz suchen die Betreiber wie folgt aus:

// CANT CHANGE THIS, ITS IN THE HEADER 
Elem& operator[](int i) const; 

// THIS IS WHAT I WANT THOUGH 
// ITS NOT IN THE HEADER, SO I CANT USE IT 
CNode * CircleList::operator()(int i) { 

    CNode * n = this->header->next; 

    if(i < 0) { 

     while(i < 0) { 
      n = (n->prev == this->header) ? (n->prev->prev) : (n->prev); 
      ++i; 
     } 

    } else if(i > 0) { 

     while(i > 0) { 
      n = (n->next == this->header) ? (n->next->next) : (n->next); 
      --i; 
     } 

    } 

    return n; 

} 

(meisten) Header in Frage:

#include "point.h" 
#include <stdlib.h> 
#include <stdio.h> 

typedef Point Elem; 
class CNode{ 
private: 
    Elem elem; 
    CNode * next; 
    CNode * prev; 

    friend class CircleList; 
}; 

class CircleList { 
public: 
    CircleList(); 
    ~CircleList(); 

    Elem& operator[](int i) const; 
    void setElemAt (int i, const Elem newElem) const; 
private: 
    CNode * header; 
    int _size; 
}; 
+4

Es tut mir leid, aber es ist nicht möglich. – AndyG

+1

Können Sie die Kopfzeile anzeigen? Wir können dies umgehen, indem wir Vererbung verwenden, wenn 'header' geschützt oder öffentlich ist. Edit: Aber das würde auch eine polymorphe Verwendung von Zeigern in den Testdateien erfordern. – AndyG

+1

Sie können nichts ** in der Kopfzeile ändern?Nun, schade ... – DeiDei

Antwort

1

Allerdings gibt es eine Funktion, die ich wirklich zur Klasse hinzufügen möchten (die operator() Funktion). Wie kann ich es als Teil der Klasse deklarieren, ohne den Header zu ändern?

Grundsätzlich können Sie nicht.

Was können Sie tun, ist entweder:

  • stammen aus der Klasse und fügen Sie Ihre operator() dort. Natürlich funktioniert das nicht, wenn anderer Code die ursprüngliche Klasse mit Wert-Semantik verwenden muss.
  • Umschließen Sie die Klasse als ein Mitglied in Ihrer eigenen Klasse, und stellen Sie eine benutzerdefinierte Konvertierung für die ursprüngliche Klasse bereit. Nicht hübsch, die meisten Fälle.
  • schwarze Magie Hinaus, die auch als Prä-Prozessor bekannt, und wickeln Sie den Header in Ihrem eigenen Header with something like dass:

    #define public \ 
        public: void operator()(void); public 
    // original header content 
    struct SomeClass { 
        // stuff 
        public: // We need this once, otherwise we're screwed 
        // other stuff 
    }; 
    // end original header content 
    #undef public 
    

    Diese offensichtlich ABI-Kompatibilität mit anderem Code bricht mit SomeClass über seinen ursprünglichen Header, though.

Dadurch wird mich retten die Funktion Körper zu 4 verschiedenen Stellen im Code zu kopieren.

Warum können Sie nicht schreiben Sie einfach eine kostenlose Funktion call_it und statt object() Sie call_it(object) in diesen 4 Plätze schreiben?

+2

Ich denke, der Grund, warum er das letzte Ding nicht machen kann, ist, dass 'call_it()' auf private Mitglieder des Objekts zugreifen muss. Er würde es brauchen, um eine Freund-Funktion zu sein, aber er kann das nicht hinzufügen. – Barmar

+0

@Barmar Oh ja. Was für eine Schande. Oder Laufzeitpolymorphismus. –

Verwandte Themen