C++ 在(!is_eof)时避免

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

我正在使用一个(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 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();