Warum haben Objekte derselben Klasse Zugriff auf die privaten Daten des jeweils anderen?
class TrivialClass {
public:
TrivialClass(const std::string& data) :
mData(data) {};
const std::string& getData(const TrivialClass& rhs) const {
return rhs.mData;
};
private:
std::string mData;
};
int main() {
TrivialClass a("fish");
TrivialClass b("heads");
std::cout << "b via a = " << a.getData(b) << std::endl;
return 0;
}
Dieser Code funktioniert. Es ist durchaus möglich, dass Objekt a von Objekt b aus auf private Daten zugreift und diese zurückgibt. Warum sollte das so sein? Ich würde denken, dass private Daten privat sind. (Ich habe zunächst versucht, Kopierkonstruktoren in der Pimpl-Sprache zu verstehen, aber dann habe ich festgestellt, dass ich diese einfache Situation nicht einmal verstanden habe.)
c++
private-members
Keith
quelle
quelle
Antworten:
Denn so funktioniert es in C ++. In C ++ funktioniert die Zugriffssteuerung auf Klassenbasis und nicht auf Objektbasis.
Die Zugriffssteuerung in C ++ ist als statische Funktion zur Kompilierungszeit implementiert. Ich denke, es ist ziemlich offensichtlich, dass es nicht wirklich möglich ist, eine sinnvolle Zugriffskontrolle pro Objekt zur Kompilierungszeit zu implementieren. Auf diese Weise kann nur die Steuerung pro Klasse implementiert werden.
Einige Hinweise zur objektbezogenen Steuerung sind in der Spezifikation für geschützten Zugriff enthalten , weshalb sie im Standard (11.5) sogar ein eigenes Kapitel enthält. Dennoch sind alle dort beschriebenen objektspezifischen Merkmale eher rudimentär. Auch hier soll die Zugriffssteuerung in C ++ auf Klassenbasis funktionieren.
quelle
void X::f(X&x)
ist der Compiler leicht zu unterscheidenthis->a
undx.a
. Es ist (immer) nicht möglich, dass der Compiler das weiß*this
undx
tatsächlich dasselbe Objektx.f(x)
ist, wenn er aufgerufen wird, aber ich könnte sehr gut sehen, dass ein Sprachdesigner dies in Ordnung findet.this
und ob sie&x
gleich sind. Um es noch schlimmer diese endet tatsächlich ein Problem ist auch mitX::f(Y& y)
, weil unser konkretes Objekt vom Typ sein könnte ,Z
dass erbt von beidenX
undY
. Kurz gesagt, es ist ein echtes Durcheinander, nicht performant, es ist schwierig, mit MI vernünftig zu arbeiten.X::f(X& x)
Zugriffe auf vorhanden sind,x.a
wird es nicht kompiliert. Es ändert sich nichts anderes, es müssen keine Überprüfungen eingefügt werden, sodass die Leistung noch gültiger Programme nicht beeinträchtigt wird. Und es wird nicht als bahnbrechende Änderung an vorhandenem C ++ vorgeschlagen, sondern als etwas, das Designer bei derprivate
ursprünglichen Einführung hätten tun können ."Privat" ist eigentlich kein Zugriffskontrollmechanismus im Sinne von "Ich habe meine Bilder auf Facebook privat gemacht, damit Sie sie nicht sehen können."
In C ++ sagt "privat" einfach, dass dies Teile einer Klasse sind, die Sie (der Codierer der Klasse) in zukünftigen Versionen usw. ändern könnten, und Sie möchten nicht, dass andere Codierer, die Ihre Klasse verwenden, sich auf ihre Existenz oder Funktionalität verlassen .
Wenn Sie eine echte Zugriffskontrolle wünschen, sollten Sie echte Datensicherheitstechniken implementieren.
quelle
Dies ist eine gute Frage, und ich bin kürzlich auf diese Frage gestoßen. Ich hatte einige Diskussionen mit meinen Kollegen und hier ist die Zusammenfassung unserer Diskussion: Dies ist beabsichtigt. Dies bedeutet nicht, dass dieses Design in allen Fällen völlig vernünftig ist, aber es muss einige Überlegungen geben, warum pro Klasse privat gewählt wird. Die möglichen Gründe, an die wir denken könnten, sind:
Erstens könnten die Kosten für die Zugriffskontrolle pro Instanz sehr hoch sein. Dies wurde von anderen in diesem Thread diskutiert. Theoretisch kann dies über diese Zeigerprüfung erfolgen. Dies kann jedoch nicht zur Kompilierungszeit und nur zur Laufzeit erfolgen. Sie müssen also die Zugriffskontrolle jedes Mitglieds zur Laufzeit identifizieren. Wenn diese verletzt wird, werden möglicherweise nur Ausnahmen ausgelöst. Die Kosten sind hoch.
Zweitens hat die Zugriffssteuerung pro Klasse einen eigenen Anwendungsfall, z. B. Kopierkonstruktor oder Operator =. Es wäre schwierig, sie zu implementieren, wenn die Zugriffskontrolle pro Instanz erfolgt.
Außerdem erfolgt die Zugriffssteuerung hauptsächlich aus Programmier- / Sprachperspektive, um den Zugriff auf den Code / das Mitglied und nicht auf die Daten zu modularisieren / zu steuern.
quelle
Es ist eine willkürliche Entscheidung für das Sprachdesign. In Ruby
private
bedeutet dies beispielsweise wirklich privat, da in "nur die Instanz auf ihre eigenen privaten Datenelemente zugreifen kann". Dies ist jedoch etwas restriktiv.Wie in den Kommentaren erwähnt, sind Kopierkonstruktoren und Zuweisungsoperatoren häufige Orte, an denen Sie direkt auf die privaten Datenelemente einer anderen Instanz zugreifen. Es gibt weniger offensichtliche Gründe dafür.
Betrachten Sie den folgenden Fall. Sie implementieren eine OO-verknüpfte Liste. Die verknüpfte Liste verfügt über eine verschachtelte Knotenklasse zum Verwalten von Zeigern. Sie können diese Knotenklasse so implementieren, dass sie die Zeiger selbst verwaltet (anstatt die Zeiger öffentlich zu haben und von der Liste verwaltet zu werden). In einem solchen Fall hätten Sie die Knotenobjekte, die die Zeiger anderer Knotenobjekte an anderen Stellen als dem typischen Kopierkonstruktor und Zuweisungsoperator ändern möchten.
quelle
Der Trick besteht darin, sich daran zu erinnern, dass sich die Daten
private
auf die Klasse und nicht auf die Instanz der Klasse beziehen. Jede Methode in Ihrer Klasse kann auf die privaten Daten einer beliebigen Instanz dieser Klasse zugreifen. Es gibt keine Möglichkeit, Daten innerhalb einer Instanz privat zu halten, es sei denn, Sie verbieten Methoden, die explizit auf private Datenelemente anderer Instanzen zugreifen.quelle
Berücksichtigen Sie zusätzlich zu allen oben genannten Antworten benutzerdefinierte Kopierkonstruktoren, Zuweisungsoperatoren und alle anderen Funktionen, die Sie für eine Klasse schreiben würden, die auf anderen Instanzen ausgeführt wird . Sie benötigen Accessor-Funktionen für alle diese Datenelemente.
quelle
Private Daten bleiben privat, bis jemand, der Zugriff darauf hat, sie anderen offenbart.
Dieses Konzept gilt auch für andere Situationen wie:
Wie könnte jemand das Geld abheben? :) :)
quelle