Folgendes meine ich:
class MyClass {
int arr1[100];
int arr2[100];
int len = 100;
void add(int* x1, int* x2, int size) {
for (int i = 0; i < size; i++) {
x1[i] += x2[i];
}
}
};
int main() {
MyClass myInstance;
// Fill the arrays...
myInstance.add(myInstance.arr1, myInstance.arr2, myInstance.len);
}
add
kann bereits auf alle benötigten Variablen zugreifen, da es sich um eine Klassenmethode handelt. Ist dies also eine schlechte Idee? Gibt es Gründe, warum ich das tun soll oder nicht?
object-oriented
c++
class-design
methods
encapsulation
Badeente
quelle
quelle
add
Methode verwenden, die ihre Interna direkt verarbeitet? Warum nur?add
Methode, die Argumente akzeptiert , aber nicht als Teil einer Klasse existiert. Nur eine reine Funktion zum Addieren von zwei Arrays.Antworten:
Es gibt vielleicht Dinge mit der Klasse, die ich anders machen würde, aber um die direkte Frage zu beantworten, wäre meine Antwort
Ja, das ist eine schlechte Idee
Mein Hauptgrund dafür ist, dass Sie keine Kontrolle darüber haben, was an die
add
Funktion übergeben wird. Sicher, Sie hoffen, dass es sich um eines der Member-Arrays handelt, aber was passiert, wenn jemand ein anderes Array mit einer Größe von weniger als 100 übergibt oder Sie eine Länge von mehr als 100 übergeben?Was passiert ist, dass Sie die Möglichkeit eines Pufferüberlaufs geschaffen haben. Und das ist eine schlechte Sache.
Um einige weitere (für mich) offensichtliche Fragen zu beantworten:
Sie mischen Arrays im C-Stil mit C ++. Ich bin kein C ++ - Guru, aber ich weiß, dass C ++ bessere (sicherere) Möglichkeiten für den Umgang mit Arrays bietet
Wenn die Klasse bereits über die Mitgliedsvariablen verfügt, warum müssen Sie sie übergeben? Dies ist eher eine architektonische Frage.
Andere Leute mit mehr C ++ - Erfahrung (ich habe es vor 10 oder 15 Jahren nicht mehr verwendet) haben möglicherweise mehr beredte Möglichkeiten, die Probleme zu erklären, und werden wahrscheinlich auch mehr Probleme haben.
quelle
vector<int>
besser geeignet; Länge wäre dann nutzlos. Alternativconst int len
, da Array variabler Länge nicht Teil des C ++ - Standards ist (obwohl es einige Compiler unterstützen, da es eine optionale Funktion in C ist).std::array
der Übergabe an Parameter nicht abfällt , dessen Größe bequemer ermittelt werden kann, das kopierbar ist und auf das mit optionaler Begrenzungsprüfung zugegriffen werden kann, ohne dass ein Overhead entsteht Arrays im C-Stil.Das Aufrufen einer Klassenmethode mit einigen Klassenvariablen ist nicht unbedingt schlecht. Dies von außerhalb der Klasse zu tun, ist eine sehr schlechte Idee und weist auf einen grundlegenden Fehler in Ihrem OO-Design hin, nämlich das Fehlen einer ordnungsgemäßen Kapselung :
len
die Länge des Arrays kennen und diese konsistent verwenden. Dies widerspricht dem Grundsatz des geringsten Wissens . Eine solche Abhängigkeit von den inneren Details der Klasse ist extrem fehleranfällig und riskant.len
modernere Arrays ändernstd::vector<int>
möchten), da Sie auch den gesamten Code mithilfe Ihrer Klasse ändern müssten.MyClass
Objekten anrichten, indem er einige öffentliche Variablen beschädigt , ohne die Regeln zu beachten (sogenannte Klasseninvarianten ).Sie sollten Ihren Code überarbeiten und:
private
oderprotected
, es sei denn, es gibt einen guten Grund, dies nicht zu tun.object.action(additional parameters for the action)
. B.:) .quelle
Wenn Sie diese Methode für Daten wiederverwenden möchten, die nicht aus dieser Klasseninstanz stammen, möchten Sie sie möglicherweise als
static
Methode deklarieren .Eine statische Methode gehört zu keiner bestimmten Instanz einer Klasse. Es ist eher eine Methode der Klasse selbst. Da statische Methoden nicht im Kontext einer bestimmten Instanz der Klasse ausgeführt werden, können sie nur auf Membervariablen zugreifen, die auch als statisch deklariert sind. In Anbetracht dessen, dass Ihre Methode
add
auf keine der in deklarierten Membervariablen verweistMyClass
, ist sie ein guter Kandidat für die Deklaration als statisch.Die in den anderen Antworten genannten Sicherheitsprobleme sind jedoch gültig: Sie überprüfen nicht, ob beide Arrays mindestens
len
lang sind. Wenn Sie modernes und robustes C ++ schreiben möchten, sollten Sie Arrays vermeiden. Verwenden Siestd::vector
stattdessen nach Möglichkeit die Klasse . Im Gegensatz zu regulären Arrays kennen Vektoren ihre eigene Größe. Sie müssen sich also nicht selbst um ihre Größe kümmern. Die meisten (nicht alle!) Ihrer Methoden führen auch eine automatische Bindungsprüfung durch, die garantiert, dass Sie eine Ausnahme erhalten, wenn Sie nach dem Ende lesen oder schreiben. Regelmäßiger Array-Zugriff führt keine gebundene Überprüfung durch, was bestenfalls zu einem Segfault führt und im schlimmsten Fall zu einer ausnutzbaren Sicherheitsanfälligkeit durch Pufferüberlauf führen kann .quelle
Eine Methode in einer Klasse manipuliert gekapselte Daten innerhalb der Klasse auf ideale Weise. In Ihrem Beispiel gibt es keinen Grund, warum die add-Methode Parameter hat. Verwenden Sie einfach die Eigenschaften der Klasse.
quelle
Das Übergeben (eines Teils davon) eines Objekts an eine Member-Funktion ist in Ordnung. Bei der Implementierung Ihrer Funktionen müssen Sie immer das mögliche Aliasing und die daraus resultierenden Konsequenzen berücksichtigen.
Natürlich kann der Vertrag einige Arten von Aliasing unbestimmt lassen, auch wenn die Sprache dies unterstützt.
Prominente Beispiele:
Self-Move-Assignment hingegen muss kein No-Op sein, auch wenn es nicht in deinem Gesicht explodieren sollte.
v.push_back(v[2]);
.std::copy()
geht davon aus, dass das Ziel nicht in der Quelle beginnt.Aber Ihr Beispiel hat verschiedene Probleme:
this
. Es verhält sich wie eine kostenlose Utility-Funktion, die sich einfach am falschen Ort befindet.Fazit: Ja, dieses Beispiel ist schlecht. Aber nicht, weil die Member-Funktion Member-Objekte übergeben bekommt.
quelle
Insbesondere ist dies aus mehreren guten Gründen eine schlechte Idee, aber ich bin mir nicht sicher, ob all diese Gründe für Ihre Frage von Bedeutung sind:
vector<int>
würde dein Leben leichter machen.quelle
Dies ist ein klassischer "C mit Klassen" -Ansatz für C ++. In Wirklichkeit würde dies kein erfahrener C ++ - Programmierer schreiben. Zum einen wird von der Verwendung von Raw-C-Arrays generell abgeraten, es sei denn, Sie implementieren eine Container-Bibliothek.
So etwas wäre angemessener:
quelle