我正在使用(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:here's a link to the documentation for the object if it is relevant
编辑:如果我尝试在循环外声明变量然后初始化它我得到一个错误
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&)'
我是否尝试错误地初始化它?
答案 0 :(得分:2)
为了达到你所需要的,你必须有一个指向在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 ++的一个非常重要的部分。 可以看到一篇更好地解释这一点的文章here。
如果我通过这样做来解释一下:
HfstTransducer t;
您正在声明该类型的对象并将其放入堆栈中。它的使用寿命仅持续到示波器结束。您无法在范围之外访问它,因为一旦范围结束就会调用析构函数。
另一方面
HfstTransducer*t = new HfstTransducer();
将t初始化为HfstTransducer类型的对象并将其放在堆中。关于堆的内容是指上面的文章,但它基本上是操作系统为您的程序分配的内存。在C ++中,您需要使用运算符 new 在堆中寻找内存,并使用 delete 运算符释放它。在C中,您可以使用 free()和 malloc()函数实现相同的功能。
除非你明确地调用它的析构函数,否则堆中的某些东西在程序的整个持续时间内都是活着的。正如您在示例中所做的那样,可以通过调用 delete t;
来完成如果不这样做会导致所有C / C ++程序员必须面对的问题,即所谓的内存泄漏。这基本上是你认为是免费的记忆,但不是因为你忘了删除/释放它。