首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试创建QT4.7 QStrings,将其插入指针数组

尝试创建QT4.7 QStrings,将其插入指针数组
EN

Stack Overflow用户
提问于 2016-11-15 04:53:42
回答 2查看 1.2K关注 0票数 1

我有一些我认为很简单的东西。类头中的声明:

代码语言:javascript
复制
public:
    int index;          // just your vanilla integer
    QString *qspointer; // allocated array with space for 1000 pointers
    // allocation occurs first thing in class code: it's definitely  there

代码:

代码语言:javascript
复制
index = 0;                        // works
qspointer[index] = new QString(); // causes error

交替码

代码语言:javascript
复制
QString *qs;                      // works
qs = new QString();               // works
qspointer[index] = qs;            // causes error

这两种情况下的编译错误都是:

代码语言:javascript
复制
"invalid conversion from QString to char"
"initializing argument 1 of 'QString& QString::operator=(char)"

这是一个QString指针。我有一个QString指针数组。我只想把指针放在指针数组中。这适用于非类项,如int指针、字符指针等,就好像这实际上不是QString指针的数组一样。但是..。在附近,我有这样的代码:

代码语言:javascript
复制
qspointers[index].~QString(); // compiler likes this.

哪个..。如果这不是一个QString指针数组..。应该会导致错误。但事实并非如此。我很困惑。:)

我显然错过了一些最基本的东西;欣赏任何指点(哈哈)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-15 06:58:15

qspointer[index] = new QString();

qspointer是指向QString(s)的指针,该指针可能指向数组并可能被索引。因此,qspointer[index]是一个QString。更准确地说,qspointer[index]表达式返回对QString的引用。new QString();返回一个指针,所以在这一行中要做的事情如下所示

代码语言:javascript
复制
QString *ptr = whatever;
QString s = ptr;

这显然是个错误。类似地,

代码语言:javascript
复制
qspointer[index] = qs;

也有同样的问题。

我有一个QString指针数组。

QString *qspointer;是指向QString数组的指针,而不是指针数组。

要创建一个指针数组,您需要如下所示:

代码语言:javascript
复制
// Declaration:
QString **qspointer; // Pointer to pointers

// Allocation:
qspointer = new QString*[1000]; // Allocated array of 1000 pointers

// Putting a pointer into the array of pointers:
qspointer[index] = new QString();

下一首,

qspointers[index].~QString();

编译,因为允许.对对象或引用调用成员。

最后,显式调用析构函数通常是一个bad idea。对堆分配的对象使用delete,对数组使用delete[]。请注意,如果有指针,则无法确定指针是指向单个对象还是指向数组。

票数 1
EN

Stack Overflow用户

发布于 2016-11-15 15:02:59

考虑到QString是隐式共享值类(并且支持自QT4.8以来的移动语义),而且我们使用的是C++而不是C,而且现在是2016年,那么您最不应该做的事情就是像1980年代那样处理指向字符串的指针。

这是你想要的

代码语言:javascript
复制
QVector<QString> strings(1000); // 1000 empty strings
strings[0] = "Foo";
strings[1] = "Bar";
strings.push_back("Moo");
Q_ASSERT(strings.back() == "Moo");

如果您使用的是std::string,这也是正确的。

代码语言:javascript
复制
QVector<std::string> strings(1000);
// etc.

如果数组的大小是固定的,则应该使用std::array

代码语言:javascript
复制
std::array<QString, 1000> strings;
strings[0] = "Foo";
strings[1] = "Bar";

请注意,上面的代码中没有一个比您想要做的要慢:

代码语言:javascript
复制
QString *strings[1000];
strings[0] = new QString("Foo");
strings[1] = new QString("Bar");

当然,这还不是全部。您需要确保字符串不泄漏,而且--想必--任何未分配的字符串都不只是悬挂的指针。当然,您不希望任何人试图盲目地复制该数组:

代码语言:javascript
复制
// DO NOT EVEN THINK OF DOING IT THIS WAY!
class MyClass {
  Q_DISABLE_COPY(MyClass)
  QString *strings[1000];
public:
  MyClass() { memset(&strings, 0, sizeof(strings)); }
  // Note: calling delete with a null pointer is perfectly safe
  ~MyClass() { for (auto string : strings) delete string; }
  void setString(int index, const QString & value) {
    if (!strings[index])
      strings[index] = new QString(value);
    else
      *strings[index] = value;
  }
  QString string(int index) const {
    return strings[index] ? *strings[index] : QString();
  }
};

这样做是可怕的,绝对没有必要在2016年。如果您的平台太老了,不能使用std::array,请使用QVarLengthArray:就像std::array一样,可以动态地调整自身的大小。按值来存储这些字符串,而不是通过指针!

通过调用析构函数等方式对字符串执行的就地生命周期管理令人痛心,而且在处理资源管理的专门类之外绝对没有任何位置。用通俗易懂的英语来说,这意味着什么?这意味着,如果,如果您有基准测试结果,表明普通容器的运行速度太慢,那么和就会确定您的算法不是罪魁祸首,而只是需要一个专门的容器来支持所述的专用算法,然后编写一个自定义容器来管理字符串的集合。然后在您的代码中使用这个容器,将恶意封装起来。在99.9999%的情况下,您将不希望实现任何这样的容器。标准库和Qt容器非常聪明。适当地使用它们,你应该都准备好了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40602291

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档