IStream2::IStream2(char *filename) {
strcpy(fn, filename);
}
Ordnet keinen Speicherplatz für fn
zu. strcpy(fn, filename);
ruft ein undefiniertes Verhalten auf, das in einen beliebigen Speicher schreibt fn
Punkte, und danach sind alle Wetten aus. Das Programm könnte alles tun.
Die richtige Antwort ist std::string
class IStream2 {
private:
std::string fn;
public:
IStream2(const char* filename); // note const. if not modifying a passed rference,
// mark it const. The compiler can make optimizations
// and can catch mistakes for you
// also the function can now receive string literals
const char* get_filename(); // another const this is because a string won't
// easily give you a non const pointer
}; <-- note the added ;
IStream2::IStream2(const char *filename): fn(filename) {
}
const char * IStream2::get_filename() {
return fn.c_str(); // get the char array from the string
}
zu verwenden, aber ich vermute, dies ist eine Übung mit Klassen in schriftlicher Form C, also zurück in die Steinzeit gehen wir. Das ist viel mehr Arbeit, weil wir den ganzen Speicher selbst verwalten müssen. Zum Beispiel müssen wir die Dreiregel einhalten. What is The Rule of Three?
Seufz.
class IStream2 {
private:
char* fn;
public:
IStream2(const char* filename); // note const char *
~IStream2(); // need destructor to clean up fn. This means we need to
// comply with the Rule of Three
IStream2(const IStream2 & src); // copy constructor
IStream2 & operator=(IStream2 src); // assignment operator
char* get_filename(); // Note: by returning a non const pointer here we
// allow the caller to tamper with the contents of
// fn and even delete it. This defeats the point
// of declaring fn private, so avoid doing this.
};
IStream2::IStream2(const char *filename) {
fn = new char[strlen(filename) +1]; // allocate storage.
// The +1 is to hold the string's NULL terminator
strcpy(fn, filename);
}
// implement copy constructor
IStream2::IStream2(const IStream2 & src) {
fn = new char[strlen(src.fn) +1];
strcpy(fn, src.fn);
}
// implement destructor
IStream2::~IStream2()
{
delete[] fn;
}
// implement assignment operator. Using Copy And Swap Idiom
IStream2 & IStream2::operator=(IStream2 src)
{
std::swap(fn, src.fn);
return *this;
}
char * IStream2::get_filename() {
return fn;
}
int main()
{
vector<IStream2> istreams;
const char* fn = "file1.txt"; // note const char *. string literals may be
// read-only memory and can't be changed
IStream2 reader2 = IStream2(fn);
istreams.push_back(reader2);
const char* fn2 = "file2.txt"; // and again const char *
IStream2 reader3 = IStream2(fn2);
istreams.push_back(reader3);
cout << istreams[0].get_filename() << endl;
return 0;
}
Da wir mit Dinosaurier wresting, werde ich nicht mit dem Rule of Five stören und Operationen verschieben, sondern sehen, wie viel ärgerlicher, es zu haben, ist dies der falsche Weg zu tun?
Mehr auf Copy And Swap Idiom
wie haben Sie Speicher für fn zugewiesen? (also hat die strcpy irgendwo zu kopieren) – Jimmy
Vielleicht, weil Sie 'fn' in beiden Fällen verwenden? Ändern Sie den Namen des zweiten 'char *' –
Dieser Code ist falsch, da Sie 'fn' zweimal definiert haben. Gib uns den richtigen Code, der das Problem verursacht. Versuchen Sie auch, 'fn'-Member zuzuordnen, wenn Sie nicht undefiniert sind. –