我正在尝试使用QT4.7和MPIR库(v.2.3.1)在C ++中编写程序。 在一些计算过程中,我需要存储动态数量的mpz_t(整数存储类型),并希望使用QList或QVarLengthArray。我已经成功地对如何做到这一点进行了基本的测试,但它看起来如此丑陋且完全错误,我想要求更好地做到这一点。
我的示例程序:
#include <QtCore/QCoreApplication>
#include <QList>
#include <qtimer.h>
#include <mpirxx.h>
#include <iostream>
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
QList<__mpz_struct> test;
std::cout << "Write ints 0 to 9 in the QList" << std::endl;
for (int i = 0; i < 10; ++i) {
mpz_t zahl;
mpz_init_set_si(zahl, i);
test.append(zahl[0]);
}
std::cout << "Check if everything is still there." << std::endl;
for (int i = 0; i < 10; ++i) {
mpz_t zahl;
zahl[0] = test.at(i);
std::cout << mpz_get_str(NULL, 10, zahl) << std::endl;
}
std::cout << "What an ugly hack." << std::endl;
QTimer::singleShot(0, &a, SLOT(quit()));
return a.exec();
}
(在Windows 7 / MSVC2010 SP1 / QT4.7.3 / MPIR2.3.1下编译) 输出是正确的,但我怀疑它是一种有效甚至安全的方式来存储mpz_t。
请让我知道如何实现这一目标:)
答案 0 :(得分:0)
如果您要在很多地方使用存储的数据,在函数等之间传递它,那么我肯定会使用QList,因为它们是implicitly shared。
这允许许多好的东西,如下所示:
void listOperation(QList<mpz_t> list)
{
// Initialize and set
mpz_t an_int;
mpz_init_set_si(an_int, 0);
list.append(an_int);
}
在这段代码中,我们按值传递'list',因此通常会出现深拷贝(复制所有数据)。但是,由于隐式共享,仅发生浅拷贝(引用副本;指向共享数据块的指针)。此外,即使要非常频繁地调用此函数,QList也会在其内部缓冲区的两侧预先分配额外的空间,因此此操作通常为O(1)(取自QList)文档。
QList(和所有QT的容器类)就像std容器一样 - 它们可以容纳任何类型的对象(甚至是基元和指针)。
使用GMP时出于两个原因,这很棘手。
更好的方法可能是使用class interface。这样你就可以用典型的c ++方式将你的mpz_t对象分配为mpz_class对象,而不必担心事情。
mpz_class an_int = 1234;
mpz_class *another = new mpz_class(1234);
更新示例: (未编译/测试)
#include <QtCore/QCoreApplication>
#include <QList>
#include <QDebug>
#include <qtimer.h>
#include <mpirxx.h>
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QList<mpz_class *> list;
qdebug() << "Write ints 0 to 9 in the QList";
for (int i = 0; i < 10; ++i)
{
test.append(new mpz_class(0));
}
qdebug() << "Check if everything is still there.";
foreach (mpz_class *item, list)
{
qdebug() << *item;
}
qdebug() << "Not so bad anymore.";
// Clean up list
qDeleteAll(list.begin(), list.end());
list.clear();
QTimer::singleShot(0, &a, SLOT(quit()));
return a.exec();
}