2016-06-11 6 views
1

Ich versuche, eine private Variable einer Klasse in einem Objekt, das innerhalb dieser Klasse initialisiert wird, zu ändern. Meine Absicht kann aus dem einfachen Beispiel unten gezogen werden. die Increment genannt von obj sollte die BaseClass::stuff erhöhen.Wie Zugriff auf private Variable von Objekt instanziiert innerhalb der Klasse

template <typename ObjectType> 
class BaseClass{ 
public: 

    int Increment(){ 
    return obj.Increment(); 
    } 

private: 
    int stuff = 0; 
    ObjectType obj; 
}; 

class ObjectType{ 
    public:  
    int Increment() 
    { 
     return BaseClass<ObjectType>::stuff++; 
    }; 
}; 

int main() { 
    BaseClass<ObjectType> base; 
    base.Increment(); // should increase stuff by 1; 
} 

Eine Möglichkeit, die ich denken kann ist vorbei Sachen als Parameter obj.Increment().

Gibt es eine Möglichkeit, dies zu erreichen, ohne es als Parameter übergeben?

+3

Verwenden 'friend' Stichwort? – fghj

+5

Ein Objekt hat keine Kenntnis davon, zu welchem ​​Objekt es gehört. Wenn Sie solches Wissen hinzufügen, erhalten Sie im Allgemeinen sehr spröden Code. –

Antwort

1

Ihr Beispiel hatte ein paar Fehler.
Einmal fixiert und hat eine friend Spezifizierer, sollte es so aussehen:

template <typename ObjectType> 
class BaseClass{ 
public: 
    friend ObjectType; 

    int Increment(){ 
     return obj.Increment(); 
    } 

private: 
    static int stuff; 
    ObjectType obj; 
}; 

template<typename T> 
int BaseClass<T>::stuff = 0; 

class ObjectType{ 
public:  
    int Increment() 
    { 
     return BaseClass<ObjectType>::stuff++; 
    }; 
}; 

int main() { 
    BaseClass<ObjectType> base; 
    base.Increment(); // should increase stuff by 1; 
} 
+0

Ich habe versucht, den Code auszuführen, wurde nicht erfolgreich. ObjectType versucht BaseClass zu nähern :: stuff (das ist kein instanziiertes Objekt) scheint das Problem zu sein, wie kann ich dieses Problem lösen? –

+0

Der Code in der Antwort kompiliert sowohl auf [kling] (https://godbolt.org/g/Dym15I) und [GCC] (https://godbolt.org/g/Z6pHQ8). Ich verstehe deinen Kommentar nicht, sorry. – skypjack

+0

oh ich verpasste die Vorlage int BaseClass :: Stuff = 0 Teil. Vielen Dank :) –

1

1, das Zeug ist kein statisches öffentliches Mitglied, also kann es nicht direkt von ClassName :: implementiert werden, id wollen Sie "BaseClass :: stuff ++" verwenden, bitte ändern Sie es als statisches public, das machen alle Objekte von BaseClass teilen sich ein Zeug.

2, andernfalls muss ObjectType die BaseClass "wissen", ObjectType :: Increment kann das BaseClass-Zeug durch einige Hilfefunktionen von BaseClass erhöhen oder den ObjectType als Freund von BaseClass machen.

Beispielcode für Objecttype eigene Baseclass:

template <typename ObjectType> 
class BaseClass{ 
public: 
    void increaseStuff() {++stuff;} 
.... 
} 

class ObjectType 
{ 
    BaseClass<ObjectType>& itsBase; 
public:  
    ObjectType(BaseClass<ObjectType>& base) : itsBase(base) 
    int Increment() 
    { 
     return itsBase.increaseStuff(); 
    }; 
}; 

aber ich denke, das Design ist sehr seltsam erscheint, bedeutet es „ich mich ändern durch andere im Besitz etwas wollen“, warum nicht direkt meine Sachen ändern. In diesem Fall denke ich, dass der Besitz von ObjectType besser ist.

Verwandte Themen