【问题标题】:Store GMP/MPIR numbers in a QList将 GMP/MPIR 编号存储在 QList 中
【发布时间】:2011-05-21 20:06:53
【问题描述】:

我正在尝试使用 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 的方式。

请告诉我如何实现这一点:)

【问题讨论】:

  • 你为什么认为它不安全?

标签: qt4 gmp qlist


【解决方案1】:

如果您要在很多地方使用存储的数据,在函数之间传递它等等。那么我肯定会使用 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);
} 

在这段代码中,我们通过值传递“列表”,因此通常会发生深层复制(复制所有数据)。但是,由于隐式共享,只会出现浅拷贝(引用拷贝;指向共享数据块的指针)。此外,即使这个函数被非常频繁地调用,QList 也会在其内部缓冲区的两侧预先分配额外的空间,所以这个操作通常是 O(1)(取自QList)文档。

QList(以及所有 QT 的容器类)就像标准容器一样——它们可以保存任何类型的对象(甚至是基元和指针)。

在使用 GMP 时这会变得很棘手,原因有两个。

  1. mpz_t 类型类似于指针,但不能使用 new
  2. mpz_clear 用于清理

更好的方法可能是使用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();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-28
    • 1970-01-01
    • 2015-05-30
    相关资源
    最近更新 更多