2010-08-08 20 views

Antwort

23

Ja, eine Member-Funktion einen Zeiger zurückgeben kann (oder Referenz) zu einem privaten Datenelement. Es gibt nichts falsch mit dieser Ausnahme, dass in den meisten Fällen die Kapselung bricht.

Das Datenelement kann sicher über die zurückgegebene Zeiger oder Referenz gelesen werden. Unabhängig davon, ob es kann geschrieben werden, hängt davon ab, ob der zurückgegebene Zeiger oder Referenz auf ein const qualifizierten Objekt (das heißt, wenn Sie ein const T* zurückkehren, werden Sie nicht in der Lage sein, der Spitz zu T ändern). Zum Beispiel:

class Example 
{ 
public: 
    int*  get()    { return &i; } 
    const int* get_const() const { return &i; } 
private: 
    int i; 
}; 

int main() 
{ 
    Example e; 

    int* p = e.get(); 
    int a = *p; // yes, we can read the data via the pointer 
    *p = 42;  // yes, we can modify the data via the pointer 

    const int* cp = e.get_const(); 
    int b = *cp; // yes, we can read the data via the pointer 
    *cp = 42;  // error: pointer is to a const int   
} 
+1

Siehe effektives C++ - Element 28. Und +1. –

+0

dieser Ansatz ist gefährlich. Es kann leicht abstürzen int * x = Beispiel() .get(); lösche x; int * y = Beispiel().bekommen(); // Abstürze –

+1

@jack london: IMO, in C++, wenn Sie manuelle Speicherverwaltung überhaupt durchführen wollen, können Sie einfach 'lösch' nicht auf beliebigen Zeigern aufrufen und erwarten, damit durchzukommen. Wenn Sie den Speicher manuell verwalten, müssen Sie wissen, was Sie tun. – UncleBens

3

Ja, es kann zurückgegeben werden und es kann gelesen und geschrieben werden. Es ist nicht mehr oder weniger gefährlich als die Adresse einer anderen Variablen zu nehmen. Public/private/protected sind syntaktische Konstrukte, die zur Kompilierungszeit überprüft werden, und sie sind nicht "ansteckend" oder Teil des Typs von etwas.

1

Ein privates Mitglied unterscheidet sich nicht von einem öffentlichen Mitglied oder einer anderen Art von Instanz. Also, ja, Sie können Zeiger auf sie nehmen und sie zurückgeben.

Wenn Zeiger auf jeder Instanz-Mitglieds nehmen, müssen Sie darauf achten, dass die übergeordnete Klasse nicht gelöscht wird und nicht aus dem Anwendungsbereich geht, es sei denn Sie diesen Zeiger nehmen und eine originalgetreue Kopie der Daten/Objekt machen es zeigt auf. Wenn es gelöscht wird oder den Gültigkeitsbereich verlässt, wird der Zeiger zu einem ungeeigneten Zeiger und Sie können ihn nicht mehr verwenden, ohne dass Ihre App explodiert (oder an nicht vorhandenen Objekten arbeitet und Ihr Programm unerwartete Dinge verdreht, aber nicht Absturz).

Design-Überlegungen:

all Ihre internen Implementierungsdetails Aussetzen möglicherweise eine Verletzung der Verkapselung. Wenn Sie jedoch nur beschreiben möchten, wie das Objekt, das Sie zurückgeben, erstellt/abgerufen wird, ist dies eine vernünftige Lösung. Auf diese Weise können Sie die Klasse ändern, um das Member-Objekt auf andere Weise zu erhalten (z. B. Abfragen einer Datei oder eines internen Wörterbuchs), ohne den Code zu unterbrechen, der diese Methoden aufruft.

1

„wäre es zum Absturz bringen oder ist es etwas sehr unsicher darüber? Kann die spitzen Daten gelesen oder geschrieben werden?“

private/protected/public haben keinen Effekt bei Laufzeit, so dass sie die Programmausführung nicht beeinflussen oder sogar das Programm abstürzen können. Sie werden bei Kompilierzeit überprüft und verursachen nur Ihren Compiler, einen Fehler beim Kompilieren zu werfen, wenn es einen Verstoß gibt.

0

Die const Qualifier werden Sie nicht auf diese Fälle schützen. James Antwort betrachtet, versuchen Sie bitte die const int * zu int *

int* cp = (int*)e.get_const(); 

Sie wird noch in der Lage sein, zu modifizieren, zu werfen.

Verwandte Themen