Ich bin dabei, einige Klassen für dynamische Arrays zu entwerfen (so etwas wie ein std :: vector). Der Grund, warum ich nicht std :: vector verwenden möchte, ist, dass meine C++ - Programme oft als eine Bibliothek verwendet werden, die von C/C++/Fortran/Delphi aufgerufen wird und daher Arrays als einen Zeiger aufnimmt. Aus Sicherheitsgründen kann ein std :: vector zur Konstruktionszeit keinen Zeiger stehlen. Mein Array1D kann als ein std :: vector arbeiten, kann aber auch mit einem Zeiger konstruiert werden. Leider scheint Visual Studio 2013 um mein Design besorgt zu sein. Bevor ich das Problem darlege, muss ich dieses Design erklären. HierDesign von dynamischen C++ - Arrays
ist das Layout meiner Klasse
template <typename T>
class Array1D {
private:
T* data_;
T* size_; // No stored as an int for optimisation purposes
bool owner_;
public:
Array1D(int n) {
data_ = new T[n];
size_ = data_ + n;
owner_ = true;
}
Array1D(T* data, int n) {
data_ = data;
size_ = data + n;
owner_ = false;
}
...
};
Die meiste Zeit, es funktioniert als std :: vector und owner_ auf true gesetzt ist. Man kann auch ein Array1D aus einem Zeiger konstruieren, und diesmal wird owner_ auf false gesetzt. In diesem Fall sind einige Operationen wie die Größenänderung nicht zulässig (durch eine Assert). Copykonstruktor und Zuordnung für das Array A sind als:
- Array1D (const Array1D & B): Tief Kopie von B in A. Nach der Konstruktion, A besitzt seinen Speicher.
- Array1D (Array1D & & B): Verschieben Sie den Vorgang in allen Fällen. Nach der Konstruktion ist der Eigentümerstatus von A derselbe wie B.
- operator = (const Array1D & B): Tiefe Kopie von B in A. Wenn A seinen Speicher nicht besitzt, ist eine Bestätigung vorhanden, um zu überprüfen, dass A und B haben die gleiche Größe. Die Zuweisung ändert den Besitzstatus von A nicht.
- operator = (Array1D & & B): Verschieben Sie den Vorgang, wenn A und B ihren Speicher besitzen. Andernfalls machen wir eine tiefe Kopie, und die Größe wird mit einem Assert überprüft, wenn A seinen Speicher nicht besitzt. Die Zuordnung nicht die Eigentümerstatus ändern A.
I die gleiche Idee meiner 2-dimensionale Array, dessen Elemente in Zeilenhauptordnung
template <typename T>
class Array2D {
private:
T* data_;
T* size_[2];
bool owner_;
public:
Array2D(int n, int p) {
data_ = new T[n];
size_[0] = data_ + n;
size_[1] = data_ + p;
owner_ = true;
}
Array1D(T* data, int n, int p) {
data_ = data;
size_[0] = data + n;
size_[1] = data + p;
owner_ = false;
}
...
Array1D<T> operator()(int i) {
Array1D<T> row(data_ + i * nb_columns(), nb_columns());
return row;
}
...
int nb_columns() const {
return static_cast<int>(size_[1] - data_);
}
};
Die Array1D zurückgegeben durch Bediener gespeichert werden angewendet wurden () (int i) besitzt keinen Speicher und enthält einen Zeiger auf die i-te Zeile des Array2D-Objekts. Ist nützlich in der folgenden Art von Code
sort(Array1D<T>& A); // A function that sorts array in place
Array2D<double> matrix(5, 100); // Construct an array of 5 rows and 100 columns
... // Fill the array
sort(matrix(3)) // Sort the 4th row
Diese „temporäre Ansichten“ für die Zeilen eines 2-dimensionalen Arrays sind sehr nützlich, aber ich ziehe sie auf temporäre Objekte zu begrenzen Aliasing zu begrenzen.
Leider bekomme ich mit Visual Studio 2013 die folgende Warnung von der IDE für die Zeilensortierung (matrix (3)): "Optionen zum Binden von r-Wert an l-Wert-Referenz ist nicht standardmäßige Microsoft C++ Erweiterung" . Ich verstehe, dass Matrix (3) ein Objekt ist, das temporär lebt und es durch eine Art verändert, die merkwürdig aussieht. Da es sich jedoch um eine "Ansicht" handelt, wird durch Modifizieren des Speichers der Speicher der Matrix modifiziert und ist nützlich.
Also folgendes meine Fragen sind:
- Ist das, was ich gültige C++ tue? (Ändern eines temporären Werts)
- Gibt es einen Fehler in diesem Design?
PS: Der vollständige Code ist unter Github verfügbar.
Der Prototyp von 'sort', den Sie angegeben haben, benötigt einen Werttyp, keinen Lvalue-Referenztyp. – ecatmur
Wie ist Ihr 'Array1D operator() (int i);' implementiert? –
Ashalynd
@ecatmut: Danke für Ihre Kommentare. Der Beitrag wurde bearbeitet. – InsideLoop