C++ 为什么初始化第二个对象会修改我的第一个对象?
我有一门课是第二流:C++ 为什么初始化第二个对象会修改我的第一个对象?,c++,class,object,C++,Class,Object,我有一门课是第二流: class IStream2 { private: char* fn; public: IStream2(char* filename); char* get_filename(); }; IStream2::IStream2(char *filename) { strcpy(fn, filename); } char * IStream2::get_filename() { return fn; } 以下是
class IStream2 {
private:
char* fn;
public:
IStream2(char* filename);
char* get_filename();
};
IStream2::IStream2(char *filename) {
strcpy(fn, filename);
}
char * IStream2::get_filename() {
return fn;
}
以下是主要代码:
vector<IStream2> istreams;
char fn[] = "file1.txt";
IStream2 reader2 = IStream2(fn);
istreams.push_back(reader2);
char fn2[] = "file2.txt";
IStream2 reader3 = IStream2(fn2);
istreams.push_back(reader3);
cout << istreams[0].get_filename() << endl;
矢量流;
char fn[]=“file1.txt”;
IStream2 reader2=IStream2(fn);
i流。向后推(读取器2);
char fn2[]=“file2.txt”;
IStream2 reader3=IStream2(fn2);
i流。向后推(读取器3);
库特
不为fn
分配存储<代码>strcpy(fn,文件名)
调用未定义的行为,将数据写入任何存储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
}
类是流2{
私人:
std::字符串fn;
公众:
IStream2(常量字符*文件名);//注意常量。如果不修改传递的引用,
//将其标记为const。编译器可以进行优化
//可以帮你抓住错误
//该函数现在还可以接收字符串文本
const char*get_filename();//另一个const这是因为字符串不会
//很容易给你一个非常量指针
}; 您如何为fn分配存储空间?(因此strcpy有地方可以复制到)该代码不正确,因为您定义了两次fn
。给我们造成问题的真实代码。如果没有,请尝试分配fn
成员。如果没有为fn分配存储,则存在strcpy行为未定义的问题。这是一个问题,如果fn在两个实例中都默认为同一位置,则可能会解释您正在经历的行为IStream2@Miyud它应该是char fn[]=“file1.txt”代码>为什么不使用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
}
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;
}