Objekt-array-Initialisierung, ohne Standard-Konstruktor
#include <iostream>
class Car
{
private:
Car(){};
int _no;
public:
Car(int no)
{
_no=no;
}
void printNo()
{
std::cout<<_no<<std::endl;
}
};
void printCarNumbers(Car *cars, int length)
{
for(int i = 0; i<length;i++)
std::cout<<cars[i].printNo();
}
int main()
{
int userInput = 10;
Car *mycars = new Car[userInput];
for(int i =0;i < userInput;i++)
mycars[i]=new Car[i+1];
printCarNumbers(mycars,userInput);
return 0;
}
Ich möchte ein Auto erstellen array, aber ich bekomme die folgende Fehlermeldung:
cartest.cpp: In function ‘int main()’:
cartest.cpp:5: error: ‘Car::Car()’ is private
cartest.cpp:21: error: within this context
gibt es eine Möglichkeit, diese Initialisierung ohne Auto() Konstruktor public?
operator new []
ruft immer den default-Konstruktor. Aber C++11 hat eine Lösung, wie gezeigt, unten.InformationsquelleAutor Dan Paradox | 2011-01-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
NÖ.
Aber lo! Wenn Sie
std::vector<Car>
, wie Sie sein sollte (nie verwendennew[]
), dann kann man genau angeben, wie die Elemente aufgebaut werden soll*.*Auch Art von. Sie können geben Sie den Wert für die Anfertigung von Kopien.
Wie diese:
Mit der zusätzlichen Funktion:
Hinweis
printCarNumbers
sollte wirklich anders gestaltet, zur Aufnahme von zwei Iteratoren bezeichnet eine Reihe.Sie können
&mycars[0]
um einen Zeiger auf das zugrunde liegende array. Aber das ist in der Regel nur nützlich für die übergabe an legacy-code, der nichtstd::vector
ist, sollten Sie aktualisieren, dass die Voraussetzung, wenn Sie können.Low-level-API ' s oft eine Puffer-und manchmal müssen Sie groß sein (zum Beispiel die übertragung von Daten von einem frame grabber). Manchmal kann man nicht vermeiden, aber du hast Recht, in den allermeisten Fällen +1
In der Tat. Meine Vermutung ist, dass die Anforderung ändern können, obwohl, weil ich bezweifle, dass die API wirklich braucht
Car*
. Vielleichtvoid*
, obwohl, und es war nur Locker sagte. 🙂Hey C ' Mon Jungs, wir haben c++11 nun statt
&mycars[0]
verwenden wir das äquivalentmycars.data()
ist ach so viel besser lesbar.InformationsquelleAutor GManNickG
Können Sie verwenden Sie placement-new wie dieser:
Verweis aus Mehr Effektiv C++ Scott Meyers:
Artikel 4 - Vermeiden Sie grundlose default-Konstruktoren
Denn es wurde gebaut, in aufsteigender Reihenfolge. Das Letzte, was gebaut werden sollte, das erste, was zerstört wurde.
die Faustregel ist erforderlich, um sicherzustellen, die richtige Reihenfolge der Zerstörung von Objekten, die voneinander abhängig sind. In diesem speziellen Fall diejenigen Objekte, die keine Abhängigkeiten haben, so dass Sie zerstört in der forward-Bestellung, die sollte ein wenig schneller und cache-freundlich. Reverse-iteration ist in der Regel sehr schlecht in Bezug auf Leistung im Vergleich zu forward-iteration.
Wie können Sie diese Lösung exception-sicher? I. e., was ist, wenn ein Konstruktor von Auto wird eine Ausnahme für einige ich? Ich vermute, man hat, um die Ausnahme zu fangen, dekonstruieren die alle bereits gebauten Auto ' s in umgekehrter Reihenfolge und rethrow...
was wird passieren, wenn ich nur
delete [] ptr;
am Ende?InformationsquelleAutor Chan
Können Sie erstellen, die ein array von Zeigern.
oder
Auto () - Konstruktor muss nicht öffentlich sein. Fügen Sie eine statische Methode, um Ihre Klasse, wird ein array erstellt:
Car *
?Ich würde ausgewählt haben dies als die richtige Antwort +1
InformationsquelleAutor Squall
Nein, gibt es nicht. New-Ausdruck erlaubt nur die Standard-Initialisierung oder keine Initialisierung überhaupt.
Die Abhilfe wäre zu reservieren raw-Speicher-Puffer mit
operator new[]
und dann konstruieren Objekte im Puffer mithilfe von placement-new mit nicht-Standard-Konstruktor.std::vector
, die dies tut. Aber +1 für die Richtigkeit.Wie kann ich reservieren raw-Speicher mit dem operator new[] ? Jeder link, der das erklärt?
Paradox: Es gibt ein Beispiel in Chans Antwort.
ITYM, dass die array-form von new-Ausdruck erlaubt nur die default-Initialisierung, die
A *a = new A(args);
ist in Ordnung. Auch diese Antwort aktualisiert werden kann, für C++11InformationsquelleAutor AnT
Gute Frage. Ich hatte die gleiche Frage, und es hier gefunden. Die wirkliche Antwort ist, @Dan-Paradox, es gibt keine standard-syntaktische Art und Weise, es zu tun. Also, all diese Antworten sind eine Vielzahl von alternativen, um das problem.
Lese ich die Antworten selbst, und nicht besonders finden, jeder von Ihnen perfekt für meine persönliche Konvention. Die Methode, die ich wahrscheinlich mit dem stick ist mit einem Standard-Konstruktor und ein
set
Methode:Den standard-Initialisierung-Konstruktor ist immer noch da, kann ich ja immer noch initialisieren, normalerweise, wenn ich nicht brauchen mehr als einen, aber wenn ich habe sonst einen
set
Methode setzt alle Variablen, die initialisiert im Konstruktor. So konnte ich etwas wie das hier tun:Dies funktioniert sehr gut, und natürlich fließt, ohne dass code suchen verwirrend.
Nun, das ist meine Antwort für diejenigen, die sich Fragen, wie zu erklären, ein array der Objekte, die initialisiert werden müssen.
Speziell für Sie, die Sie versuchen, geben ein array von Autos, die Identitäten, die ich hatte angenommen, Sie wollen immer eindeutig sein. Sie könnten es tun, mit meiner Methode, die ich oben erklärt, und dann in der
for
Schleife verwendeni+1
als argument geschickt, um dieset
Methode - aber von was ich gelesen habe in deinen Kommentaren, es scheint, wie Sie wollen, die ids mehr intern initiiert, so dass standardmäßig jedes Fahrzeug hat eine eindeutige id, auch wenn jemand anderes nutzt Ihre KlasseCar
.Wenn dies ist, was Sie wollen, können Sie die Verwendung einer statischen member:
In dieser Weise, Sie müssen nicht bei allen sorgen über die Einleitung der Identitäten, da Sie verwaltet intern.
InformationsquelleAutor Codesmith
Können Sie immer erstellen Sie ein array von Zeigern , die auf Auto-Objekte und erstellen Sie Objekte in einer for-Schleife, wie Sie wollen, und speichern Sie Ihre Adresse in das array , zum Beispiel :
Hinweis: neue Methode !!!
Alles, was Sie haben, zu ändern, neue Methode ist der Umgang mit Autos, als Wegweiser, als statische Objekte
in-parameter und bei Aufruf der Methode printNo()
zum Beispiel :
am Ende der main ist gut, um zu löschen Sie alle dynamicly Speicher zugewiesen, wie dies
Hoffe, dass ich geholfen, cheers!
InformationsquelleAutor kondilidisn
In C++11 ist
std::vector
Sie instanziieren können Elemente in-place-mithilfeemplace_back
:Voila!
Auto() default-Konstruktor nie aufgerufen.
Löschung wird automatisch geschehen, wenn
mycars
geht out of scope.Warum Sie benötigen Konstruktor-Aufruf für array-Referenzen
InformationsquelleAutor rustyx
Einen Weg, das zu lösen ist, um eine statische factory-Methode zur Zuweisung des array, wenn Sie aus irgendeinem Grund möchten, geben Konstruktor privat.
Aber warum sind Sie immer einen Konstruktor public und private?
Aber jedenfalls eine weitere Möglichkeit ist zu erklären, dass die öffentlichen Konstruktor mit default-Wert
Aber das ist kein Kopie-Konstruktor.
du hast Recht, aber ich möchte vermeiden Standardkonstruktor sowieso. Alle Fahrzeuge müssen über eine id verfügen
In diesem Fall können Sie die factory-Methode mit dimenions-und Initialisierungs-Liste. Die factory-Methode wäre verantwortlich für die Erstellung und array und initialisiert, die id für jedes Objekt. - Initialisierung-Funktion kann auch privat sein.
InformationsquelleAutor Neera
Ich glaube nicht, dass es Typ-sicher-Methode, die das tun können, was Sie wollen.
InformationsquelleAutor Dagang
Können Sie die in-operator, der neue. Das wäre ein bisschen schrecklich, und ich würde empfehlen, in einer Fabrik.
Definieren und eine entsprechende zerstören, so entspricht das neue in diesem.
InformationsquelleAutor Keith
Mein Weg
InformationsquelleAutor Mitch Pisa