C++ 文件*、fopen_s和初始化列表
我有一个这样声明的类(仅显示相关部分): 构造函数将打开一个文件:C++ 文件*、fopen_s和初始化列表,c++,initialization-list,C++,Initialization List,我有一个这样声明的类(仅显示相关部分): 构造函数将打开一个文件: X::X(int x) : _x(x) { int err = fopen_s(&stream, "myfile.txt", "w"); fputs("some text", stream); ... } 它用于另一个类,如: class Y { public: Y(); private: X myX; } 在Y的构造函数中,通过初始化列表初始化myX,并在其上
X::X(int x) : _x(x)
{
int err = fopen_s(&stream, "myfile.txt", "w");
fputs("some text", stream);
...
}
它用于另一个类,如:
class Y
{
public:
Y();
private:
X myX;
}
在Y的构造函数中,通过初始化列表初始化myX,并在其上调用一个方法:
Y::Y() : myX(100)
{
myX.init();
}
当我逐步遍历X的构造函数时,流被分配并写入,没有错误。如果我在Y的构造函数的左大括号处放置断点,则stream的值与X的构造函数中的值相同。但是,当我进入Y的构造函数体时,stream的值会发生变化,并且下次使用它(例如在init()中)会导致访问冲突。如果我将Y更改为存储指向X的指针,而不是直接引用,并在堆上分配X,则一切正常。我怀疑这与fopen_s分配文件*的位置有关,但我无法证实这一点。有人能解释为什么失败吗?你也应该显示init(),考虑不要在你的构造函数中做工作,然后添加一个init给y,然后调用它的x()上的init。如果你做了一个干净的重建?侧栏,这个错误仍然存在:标识符(变量名、类型、宏定义等等)。前导下划线由编译所依据的实现保留。也就是说,
\ux
是一个坏习惯,你现在应该在学习的过程中改掉它x_u
,x
,等等都很好。另外,如果需要在构造函数中执行此操作,请声明x private的默认构造函数,这样您就不会意外地在其中创建一个包含无效文件*的x。
Y::Y() : myX(100)
{
myX.init();
}