IStream2::IStream2(char *filename) {
strcpy(fn, filename);
}
fn
の記憶域は割り当てられません。 strcpy(fn, filename);
は、未定義のビヘイビアを何らかの記憶域に書き込むと、fn
がポイントし、その後はすべてのベットがオフになります。プログラムは何でもできる。
正しい答えは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
}
を使用することです。しかし、私はそう戻って、我々は行く石器時代に、これはクラスとCを書くことの練習である疑いがあります。私たちは自分ですべてのメモリを管理しなければならないので、これ以上の作業はありません。たとえば、3つのルールを守る必要があります。 What is The Rule of Three?
私たちが恐竜とwrestingされているので
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;
}
、私はRule of Fiveを気にして操作を移動し、それはこの間違った方法をしなければならないことですどれだけ多くの迷惑は表示されませんか?
詳細については、Copy And Swap Idiom
どのようにfnのストレージを割り当てましたか? (したがってstrcpyはどこかにコピーされます) – Jimmy
どちらの場合でも 'fn'を使用している可能性がありますか?第2の 'char *'の名前を変更してください –
'fn'を2回定義したので、そのコードは正しくありません。問題の原因となる実際のコードを教えてください。また、 'fn'メンバを割り当てようとします。 –