C++ 在(!is_eof)时避免
我正在使用一个(C++)库,其中需要用流初始化对象。随库提供的示例代码使用以下代码:C++ 在(!is_eof)时避免,c++,stream,scope,while-loop,state-machine,C++,Stream,Scope,While Loop,State Machine,我正在使用一个(C++)库,其中需要用流初始化对象。随库提供的示例代码使用以下代码: // Declare the input stream HfstInputStream *in = NULL; try { // This sets up the special stream object for the later object (see below) in = new HfstInputStream("pathToFile.hfsto"); } // catch er
// Declare the input stream
HfstInputStream *in = NULL;
try
{
// This sets up the special stream object for the later object (see below)
in = new HfstInputStream("pathToFile.hfsto");
}
// catch errors...
// {omitted}
// Initialize the object
while (not in->is_eof()) {
if (in->is_bad())
{
std::cerr << "ERROR: Stream cannot be read." << std::endl;
exit(1);
}
// Here we initialize the object using the stream
HfstTransducer t(*in);
}
我是否试图错误地初始化它?为了实现所需,必须在while范围之外声明一个指向对象的指针,如下所示:
//Declare the pointer to the object outside the while score. This way it will be available to you even outside of the while
HfstTransducer* t = 0;
// Initialize the object
while (not in->is_eof()) {
if (in->is_bad())
{
std::cerr << "ERROR: Stream cannot be read." << std::endl;
exit(1);
}
// Here we initialize the object using the stream only if it's not already been initialized before
// thanks to Necrolis for the observation
if(t == 0)
t = new HfstTransducer(*in);
}
编辑:回答有关指针与普通对象的一般问题:
这是C/C++的一个非常重要的部分。
可以看到一篇更好地解释这一点的文章
如果我用几句话来解释它,那么:
HfstTransducer t;
您正在声明该类型的对象并将其放入堆栈中。它的生命周期仅持续到范围结束。您无法在范围外访问它,因为一旦范围结束,就会调用它的析构函数
另一方面
HfstTransducer*t = new HfstTransducer();
将t初始化为HFSTTransformer类型的对象,并将其放入堆中。关于堆是什么,请参阅上面的文章,但它基本上是操作系统分配给程序的内存。在C++中,用堆中的新操作符请求内存,并用删除操作符释放内存。在C中,使用free()和malloc()函数可以实现同样的效果
因此,堆中的某些内容在程序的整个过程中都是活动的,除非显式调用其析构函数。正如您在示例中通过调用delete t所做的那样
否则,所有C/C++程序员都将面临所谓的内存泄漏。这基本上就是你认为是空闲的内存,但不是因为你忘记删除/释放它。
hfstt(*in)代码>在循环范围内。但是
中的HfstInputStream*不是,您可以在循环外访问它,并使用它初始化另一个hfstconverter
对象,或者只使用HfstInputStream
指针。。。当然,除非HfstTransducer
构造函数具有移动语义并在中擦除HfstInputStream*。您的问题是不能访问循环外部的t(HfstTransducer类型的对象)?如果是这样,那么您可以在堆上的循环外部声明它,并使用new操作符在循环内部初始化它。如果不是的话,我只是误解了你的问题:如果我不清楚的话,那就赶快。我的意思是,我希望将HFSTTransformer对象保持在循环外部,并在HFSTTransformer初始化后忘记流,而不是每次都构建一个新的HFSTTransformer对象。如果这是可能的,那就是我的目标。左撇子,你理解对了。我尝试了你的建议,但出现了一个错误,请查看我的编辑。谢谢你的帮助。好的,问题是我只是尝试错误地初始化它。当我在{t=hfstconsensor(*in);}
时,它工作得非常好。Lefteris,谢谢你给了我我需要的提示。我几秒钟前就发现了这一点,但你的回答也增加了我需要的细节(比如打电话删除)。非常感谢你的帮助和彻底的回答!另外,在第二行声明指针与常规对象之间有什么区别?您需要检查t
是否尚未在每次循环迭代中创建(这意味着t
必须初始化为NULL
),否则会泄漏内存。因此,我应该进行类似if(t==NULL)的检查{t=new HfstTransducer(*in)}
?Dougalg我更改了回复,添加了一些关于堆和堆栈的信息,以便您可以了解它们是什么。@Necrolis.Correct observation!!将再次编辑以实现此目的
HfstTransducer t;
HfstTransducer*t = new HfstTransducer();