Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从QString到类类型_C++_Qt_Class - Fatal编程技术网

C++ 从QString到类类型

C++ 从QString到类类型,c++,qt,class,C++,Qt,Class,我有相当多的类都来自同一个父类,我需要从一个简单的QString实例化其中的任何一个类 我设想使用一个带有QString键的QMap,并将类作为值引用,就可以做到这一点 class Feat : public QObject { ... } // Base class QMap<QString, ...> feats; 但是我不知道从这里该怎么做,我想要的语法是什么。由于构造函数不是一个普通函数,您需要类似工厂模式的东西,即存储返回给定类型的新实例的函数;一种简单的C++11+方

我有相当多的类都来自同一个父类,我需要从一个简单的QString实例化其中的任何一个类

我设想使用一个带有QString键的QMap,并将类作为值引用,就可以做到这一点

class Feat : public QObject { ... } // Base class

QMap<QString, ...> feats;

但是我不知道从这里该怎么做,我想要的语法是什么。

由于构造函数不是一个普通函数,您需要类似工厂模式的东西,即存储返回给定类型的新实例的函数;一种简单的C++11+方法是将一个QString映射到一个std::函数,该函数将新实例作为指向基类的指针返回:

QMap<QString, std::function<Feat *()>> feats;
feats["Feat1"] = []() { return new Feat1; };
feats["Feat2"] = []() { return new Feat2; };
如果您确信不需要在那些lambda中捕获任何东西,那么您也可以避免std::函数开销,但是我不会担心这一点,除非您有一些真正的原因来解释构建时间?运行时开销?为了避免它


顺便说一句,即使Digia也承认Qt容器处于生命支持模式,因此,除非您有充分的理由使用它们,例如稳定的二进制接口,不同编译器之间更一致的性能-尽管通常更差,但内置的,STL对应项,如std::map或std::unordered_map。

如果类继承自QObject,则可以使用从其名称作为字符串构造实例。元对象系统是Qt的关键部分,它提供了类型名和类型ID之间的映射

您需要首先注册您的类型,以便元对象系统知道如何处理它,使用:

Q_DECLARE_METATYPE(Feat)
然后,无论何时,只要您想根据对象的名称构造对象,您都可以使用:

int type_id = QMetaType::type("Feat");
void *obj = QMetaType::create(type_id);
现在obj指向一个动态分配的Feat实例。请注意,在使用完QMetaType::destroytype_id,obj;后,需要释放该对象;;用某种类型的保护指针std::unique_ptr、QPointer等将其封装。;或者确保它有一个QObject父对象,该父对象将自动释放它


另外,请注意,您需要注册希望以这种方式使用的每个类型。

它们是如何构造的?哪些参数?什么步骤??它们建成后,你会如何处理它们?你知道什么是继承,了解LSP吗?你没有充分描述这个问题。我认为参数不重要,因为它们都有相同的构造函数定义。我知道继承的原理,但从来没有听说过LSP。关于可预测的性能:我想说的恰恰相反,标准容器具有更可预测的性能,因为您确切地知道,当使用Qt的COW容器进行复制时,即使是基于范围的for循环或通过索引的读取访问,如果容器不是const,也可能会或可能不会导致复制。@Corristo:hmm我认为可预测的确是一个错误的术语;我要说的是,在所有情况下使用同一个库时,编译器之间都是一致的,与标准库不同,这在g++/libstdc++、clang/libc++、VC++/Dinkumware之间是完全不同的。@Yakk AdamNevraumont:如果您希望返回一些智能指针,请根据需要调整[…];这只是一般的想法,细节取决于OP将如何使用它-特别是,处理QObject派生类时,通常您只需返回已为父对象的原始指针。在这种情况下,父对象当然需要作为构造函数参数传入,所以就不需要智能指针了。好吧,我会尽快尝试,谢谢,是的,当使用QObject派生类时,原始指针似乎非常好,正如我到目前为止学到的一样。这看起来很有趣,我意识到我知道qvariant使用的元类型,但我不知道这一点。那么我需要注册每一种衍生的专长类型?是的,你必须为你想在元对象系统中使用的每一种类型使用Q_DECLARE_元类型。这有点烦人,但听起来额外的灵活性是值得的。
int type_id = QMetaType::type("Feat");
void *obj = QMetaType::create(type_id);