繁体   English   中英

如何继承QVector?

[英]How to subclass QVector?

我有一个名为Symbol的类,我想创建一个QVector子类(Symbols)以添加一些有用的方法。 但是,当我使用另一个类A中的Symbols时,编译器给出错误“ Symbols not named a type”。

class Symbols: public QVector< Symbol >
{
public:
    Symbols() {}

    // Useful methods
    QSymbol findSymbol(const QString &name);

    // ...
};

class A
{
private:
    Symbols symbols;
};

是否正确分类了?

为什么在编译类A时出现“符号未命名类型”?

通常不建议从容器中获取。 您几乎总是想要“具有A”关系,否则您的班级将公开班级用户可以使用的成员,这可能会破坏状态。

而且看起来您正在尝试在类中实现查找,这意味着QMap或QHash可能是更合适的容器

这些评论之后,我必须将此添加到答案中。 不要继承QVector<T> 该类型没有虚拟析构函数,在这种情况下,继承关系( IS-A )中最重要的部分将被破坏。

查看您的类Symbols,并想像一下随着时间的流逝,它的复杂性增加了,所以现在在某个地方有析构函数和构造函数:

class Symbols: public QVector<Symbol>
{
    ~Symbols()
    {
        important_cleanup_here();
    }
};

您可能会认为SymbolsQVector<Symbol>的子类型,因此您的一位客户编写了这样的内容:

QVector<Symbol>* symbols = new Symbols(); 

听起来不错吧? 毕竟, Symbols扩展了QVector<Symbol> ,所以它可以遵循替代原理,对吗? 错误。 由于QVector<T>析构函数不是虚拟的,因此不会调用Symbols析构函数!

delete symbols;

更糟糕的是,这是未定义的行为,编译器可以执行他想做的任何事情。

如果您只想使用方便的方法,请创建一个非方法即可为您解决问题

QSymbol findSymbol(const QVector<QSymbol>&, const QString& name);

(有关此内容的参考,请阅读Scott Meyer的这篇惊人文章: http : //www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197

当然,在您的示例中,没有什么可害怕的。 但是,当您可以毫无忧虑地使用合成时,为什么要对您的一门课加重负担呢?

另外,请参考此(以及其他一些报告)有关此的错误: https : //bugreports.qt.io/browse/QTBUG-8292

除了所有其他问题,我在这里可以看到一个问题:

class Symbols: public QVector<Symbol>
{
      QSymbol findSymbol(const QString &name);
};

根据我所看到的,应该是

class Symbols: public QVector<Symbol>
{
      Symbol findSymbol(const QString &name);
};

要么

class Symbols: public QVector<QSymbol>
{
      QSymbol findSymbol(const QString &name);
};

我找到了!

问题是我有一个循环依赖。

类符号:

#ifndef SYMBOLS_H
#define SYMBOLS_H
#include <QVector>
#include "A.h"
#include "symbol.h"

class Symbols: public QVector<Symbol>
{
public:
    Symbols() {}
};
#endif // SYMBOLS_H

A类:

#include "symbols.h"
class A {
   private:
     QSymbols symbols;
}

#include“ Ah”引发错误。 在那里是因为我有一个对类A的引用的函数。我必须搜索如何解析循环引用:)。

非常感谢大家。

您遇到了几个为什么代码无法编译的问题:

  • 如果类声明在同一文件中,则缺少分号。 失败的话,您当然需要将包含Symbol声明的头文件包含在使用它的文件中。

  • 您正在使用QSymbol返回值而不是Symbol。

  • 您不包括QVector。

这是一个编译代码。

main.cpp

#include <QVector>

class Symbol
{
};

class Symbols: public QVector<Symbol>
{
    public:
      Symbols() {}

      Symbol findSymbol(const QString &name) {}
};


class A {
       Symbols symbols;
};

int main()
{
    return 0;
}

main.pro

TEMPLATE = app
TARGET = main
QT = core
SOURCES += main.cpp

建立

qmake && (n)make

话虽这么说,QSymbol也看起来很可疑,因为Qt中没有这样的类,您真的不应该使用这样的名称,因为那样只会引起混乱。 同样,以前缀开头所有类只是愚蠢的,并且仅出于兼容性原因在Qt中开始,而不是因为它比名称空间更好。

另外,请不要接受这样的论点,即子类化容器最终不是一个好主意。 QStringList是一个很好的例子,证明了声明的错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM