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++ 从名称的类型和字符串返回指针_C++_Qt - Fatal编程技术网

C++ 从名称的类型和字符串返回指针

C++ 从名称的类型和字符串返回指针,c++,qt,C++,Qt,如何从一个已知类型的名称字符串返回一个现有指针?假设我创建了一个叫做map1的地图和一个叫做vec1的向量。我想编写一个函数,从map1返回map1,从vec1返回vec1,并添加一个参数,指定每个参数的各自类型 这可能吗 我的最终目标是以QString的形式获得一个QWidget,因为我正在处理大量的QWidget,尽管答案应该与框架无关,对吧?您需要执行某种动态调度。要做到这一点,您只需从您的建议开始: enum class types { A = 0, B = 1 }; void (*ha

如何从一个已知类型的名称字符串返回一个现有指针?假设我创建了一个叫做map1的地图和一个叫做vec1的向量。我想编写一个函数,从map1返回map1,从vec1返回vec1,并添加一个参数,指定每个参数的各自类型

这可能吗


我的最终目标是以QString的形式获得一个QWidget,因为我正在处理大量的QWidget,尽管答案应该与框架无关,对吧?

您需要执行某种动态调度。要做到这一点,您只需从您的建议开始:

enum class types { A = 0, B = 1 };
void (*handlers[])(void*) = { &HandleA, &HandleB };

::std::unordered_map<::std::string, ::std::tuple<types, void*>> registry;
现在,原型是void HandleAA*

简单地将对象添加到注册表 使用当前代码,您可以向注册表添加对象,如下所示:

A a;
registry.emplace("A #1", ::std::make_tuple(types::A, &a));
虽然这样做很完美,但我们想做一些更优雅的事情。让我们首先将枚举类类型更改为一些也知道要表示它的类型的类型:

template<typename T> struct types;
template<> struct types<A> { static const size_t id = 0; };
template<> struct types<B> { static const size_t id = 1; };

元对象系统已经处理了这个问题,所以答案是特定于框架的,因为通常需要一个代码生成器来获取关于C++类型的元数据,而这些类型是不可用的。

QLineEdit * ed = ...;
ed->setObjectName("myObject");

... elsewhere in the code

foreach(QWidget * w, QCoreApplication::allWidgets()) {
  // Lookup by name
  if (w->objectName() == "myObject") {
    ...
  }
  // Lookup by type
  if (qobject_cast<QLineEdit*>(w)) {
    ...
  }
}
查找工作如下所示:

widgets2->lookup<QLineEdit>("myObject")->setText("foo");
我正在利用QObject和QPointer使小部件注册表对小部件删除安全—您永远不会得到一个悬空指针

如果您愿意,还可以跟踪对象名称的更改:QObject发出objectNameChanged信号


当然,所有这些都是围绕代码的破损设计进行的骇人听闻的黑客攻击。您需要这样做的事实意味着您将业务逻辑与GUI紧密耦合。您应该使用某种类型的模型视图体系结构。

如果要正确处理范围等,您将进入调试信息领域。。为什么不自己编写一个简单的对象注册表呢?我不完全理解您想要做什么。这是可以做到的,可能有人会很快回答,但我怀疑有更好的方法来完成您试图做的事情。QObject,因此QWidget已经支持这一点。注意,对于C++对象来说,这是完全不可能的。你必须把名字字符串提供给代码,而不是仅仅声明它。我怀疑有一个更好的方法来做你想做的任何事情。肯定您希望这样做,这表明您的代码设计已经腐朽。
::std::unordered_map<::std::string, ::std::tuple<size_t, void*>> registry;
template<typename T>
void insert(::std::string const& name, T* object)
{
    registry.emplace(name, ::std::make_tuple(types<T>::id, static_cast<void*>(object)));
}
A a;
insert("A #1", &a);
lookup("A #1");
QLineEdit * ed = ...;
ed->setObjectName("myObject");

... elsewhere in the code

foreach(QWidget * w, QCoreApplication::allWidgets()) {
  // Lookup by name
  if (w->objectName() == "myObject") {
    ...
  }
  // Lookup by type
  if (qobject_cast<QLineEdit*>(w)) {
    ...
  }
}
class Widgets {
  typedef QMap<QString, QPointer<QWidget>> Data;
  mutable Data m_map;
public:
  Widgets() {
    foreach(QWidget * w, QCoreApplication::allWidgets()) {
      if (w->objectName().isEmpty()) continue;
      m_map.insert(w->objectName(), w);
    }
  }
  QWidget * lookupWidget(const QString & name) const {
    Data::iterator it = m_map.find(name);
    if (it == m_map.end()) return nullptr;
    QWidget * w = it->data();
    if (!w) m_map.erase(it); // The widget doesn't exist anymore
    return w;
  }
  template <typename T> T * lookup(const QString & name) const {
    return qobject_cast<T*>(lookupWidget(name));
  }
  void setName(QWidget * w, const QString & name) {
    Q_ASSERT(! name.isEmpty());
    w->setObjectName(name);
    m_map.insert(name, w);
  }
};
class Widgets2 {
  typedef QPair<QString, QString> Key;
  typedef QMap<Key, QPointer<QWidget>> Data;
  mutable Data m_map;
  static Key keyFor(QWidget * w) {
    return qMakePair(w->objectName(),
      QString::fromLatin1(w->metaObject()->className()));
public:
  Widgets2() {
    foreach(QWidget * w, QCoreApplication::allWidgets()) {
      if (w->objectName().isEmpty()) continue;
      m_map.insert(keyFor(w), w);
    }
  }
  QWidget * lookupWidget(const QString & name, const QString & type) const {
    Data::iterator it = m_map.find(qMakePair(name, type));
    if (it == m_map.end()) return nullptr;
    QWidget * w = it->data();
    if (!w) m_map.erase(it); // The widget doesn't exist anymore
    return w;
  }
  template <typename T> T * lookup(const QString & name) const 
  {
    return qobject_cast<T*>(lookupWidget(name, 
      QString::fromLatin1(T::staticMetaObject.className())));
  }
  void setName(QWidget * w, const QString & name) {
    Q_ASSERT(! name.isEmpty());
    w->setObjectName(name);
    m_map.insert(keyFor(w), w);
  }
};
widgets2->lookup<QLineEdit>("myObject")->setText("foo");