避免 while (!is_eof)

发布于 2025-01-03 22:07:46 字数 1294 浏览 1 评论 0原文

我正在使用一个(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 循环之外使用。我必须用流来声明它(据我所知),所以我无法声明然后用循环内的流来初始化它。

我的问题是(1)我错了吗?我实际上可以以某种方式在循环之外声明它吗? (2) 是否有另一种(更好的)方法可以完全避免循环。例如,如果我要使用 try/catch 并捕获异常。

我对 C++ 很陌生,正在寻找最佳实践,所以请让我知道是什么。谢谢。

另外,需要明确的是,我希望创建一个使用该对象的持久版本的类,这样我就不必在每次需要使用这些对象时不断地创建/销毁这些对象。

PS:这里是对象文档的链接(如果相关)

编辑:如果我尝试在循环外声明变量然后初始化它我收到错误消息

HfstTransducer t;
while (not in->is_eof()) {
    t(*in);
}
// ERROR: main.cpp:47:0 main.cpp:47: error: no match for call to '(hfst::HfstTransducer) (hfst::HfstInputStream&)'

我是否尝试错误地初始化它?

I'm working with a (C++) library, where the object needs to be initialized with a stream. The sample code provided with the library uses this code:

// 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);
}

My problem is that this object cannot be used outside of the while loop because of scoping. and I have to declare it with the stream (as far as I can tell), so I can't declare and then initialize it with the stream inside the loop.

My questions are (1) am I wrong? Can I actually declare it outside the loop somehow? (2) is there another (better) way to do this that avoids the loop altogether. For example, if I were to use try/catch and catch the exceptions.

I'm very new to C++ and looking to find out best practices, so please let me know what's what. Thanks.

Also, to be clear, I'm looking to make a class that would use a persistant version of this object so I don't have to constantly create/destroy these objects every time I need to use them.

PS: here's a link to the documentation for the object if it is relevant

EDIT: If I try to declare the variable outside the loop and then initialize it I get an error

HfstTransducer t;
while (not in->is_eof()) {
    t(*in);
}
// ERROR: main.cpp:47:0 main.cpp:47: error: no match for call to '(hfst::HfstTransducer) (hfst::HfstInputStream&)'

Am I trying to initialize it incorrectly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独闯女儿国 2025-01-10 22:07:46

为了实现您所需要的,您必须有一个指向在 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);
}

这将声明 HfstTransducer 类型的对象并将其初始化到堆中。这意味着在离开作用域后,析构函数不会被单独调用,而是必须通过调用显式调用它:

delete t;

编辑:回答关于指针与普通对象的一般问题:

这是 C/ 的一个非常重要的部分C++。
可以在此处查看一篇文章来更好地解释这一点。

如果我用几句话来解释它:

HfstTransducer t;

您正在声明该类型的对象并将其放入堆栈中。它的生命周期仅持续到范围结束。您无法在作用域外访问它,因为作用域结束后就会调用它的析构函数。

另一方面

HfstTransducer*t = new HfstTransducer();

将 t 初始化为 HfstTransducer 类型的对象并将其放置在堆中。关于堆的含义,请参阅上面的文章,但它基本上是操作系统分配给程序的内存。在 C++ 中,您可以使用运算符 new 请求堆中的内存,并使用删除运算符释放内存。在 C 语言中,您可以使用 free()malloc() 函数实现相同的目的。

因此,除非您显式调用其析构函数,否则堆中的某些内容在程序的整个持续时间内都处于活动状态。正如您可以通过调用 delete t; 在示例中执行的操作,

如果不这样做,将导致所有 C/C++ 程序员都必须面对的问题,即所谓的内存泄漏。这基本上是您认为是免费的内存,但并不是因为您忘记删除/释放它。

In order to achieve what you need, you have to have a pointer to the object declared outside of the while scope like that:

//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);
}

This will declare and initialize an object of HfstTransducer type into the heap. This means that the destructor will not be called on its own after you leave scope but that you have to explicitly call it by calling:

delete t;

EDIT: To answer to your general question about pointer vs normal object:

This is a very important part of C/C++.
An article to better explain this can be seen here.

If I were to explain it in a few words by doing:

HfstTransducer t;

You are declaring an object of that type and putting it in the stack. Its life-time lasts ONLY until the end of the scope. You are not able to access it out of scope, since its destructor will be called as soon as the scope ends.

On the other hand

HfstTransducer*t = new HfstTransducer();

initializes t as an object of HfstTransducer type and places it in the heap. For what the heap is refer to the article above, but it basically is the memory allocated to your program by the operating system. In C++ you ask for memory in the heap with the operators new and free it with the delete operator. In C you achieve the same with the free() and malloc() functions.

So something in the heap is alive for the whole duration of your program unless you explicitly call its destructor. As you can do in the example by invoking delete t;

Failure to do so leads to what all C/C++ programmers have to face, the so called memory leaks. Which is basically memory you thought is free but is not because you forgot to delete/free it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文