Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.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++应用程序中有基类和几个派生类。 您希望枚举从该基派生的所有类,而不实例化派生类,比如在“类名”列表框中向用户显示它们。显然,所需的信息就在应用程序的某个地方。如何检索它?_C++_Derived - Fatal编程技术网

枚举C+中的派生类+;可执行 假设你在C++应用程序中有基类和几个派生类。 您希望枚举从该基派生的所有类,而不实例化派生类,比如在“类名”列表框中向用户显示它们。显然,所需的信息就在应用程序的某个地方。如何检索它?

枚举C+中的派生类+;可执行 假设你在C++应用程序中有基类和几个派生类。 您希望枚举从该基派生的所有类,而不实例化派生类,比如在“类名”列表框中向用户显示它们。显然,所需的信息就在应用程序的某个地方。如何检索它?,c++,derived,C++,Derived,无法检索。大多数情况下,您在运行时不知道类名,并且无法获取类的列表。如果您不想实例化所有需要的类,唯一的选择是手动构建列表。您可以添加静态注册器元素。大概是这样的: Base.hpp: #include <string> #include <typeindex> #include <unordered_map> using typemap = std::unordered_map<std::type_index, std::string>; s

无法检索。大多数情况下,您在运行时不知道类名,并且无法获取类的列表。如果您不想实例化所有需要的类,唯一的选择是手动构建列表。

您可以添加静态注册器元素。大概是这样的:

Base.hpp:

#include <string>
#include <typeindex>
#include <unordered_map>

using typemap = std::unordered_map<std::type_index, std::string>;

struct Base
{
    /* ... */
    static typemap & registry();
};

template <typename T> struct Registrar
{
    Registrar(std::string const & s) { Base::typemap()[typeid(T)] = s; }
};
#include "Base.hpp"
typemap & Base::registry() { static typemap impl; return impl; }
#include "Base.hpp"

struct DerivedA : Base
{
    static Registrar<DerivedA> registrar;
    /* ... */
};
#include "DerivedA.hpp"
Registrar<DerivedA> DerivedA::registrar("My First Class");
DerivedA.hpp:

#include <string>
#include <typeindex>
#include <unordered_map>

using typemap = std::unordered_map<std::type_index, std::string>;

struct Base
{
    /* ... */
    static typemap & registry();
};

template <typename T> struct Registrar
{
    Registrar(std::string const & s) { Base::typemap()[typeid(T)] = s; }
};
#include "Base.hpp"
typemap & Base::registry() { static typemap impl; return impl; }
#include "Base.hpp"

struct DerivedA : Base
{
    static Registrar<DerivedA> registrar;
    /* ... */
};
#include "DerivedA.hpp"
Registrar<DerivedA> DerivedA::registrar("My First Class");
#包括“Base.hpp”
结构DerivedA:基础
{
静态注册;
/* ... */
};
DerivedA.cpp:

#include <string>
#include <typeindex>
#include <unordered_map>

using typemap = std::unordered_map<std::type_index, std::string>;

struct Base
{
    /* ... */
    static typemap & registry();
};

template <typename T> struct Registrar
{
    Registrar(std::string const & s) { Base::typemap()[typeid(T)] = s; }
};
#include "Base.hpp"
typemap & Base::registry() { static typemap impl; return impl; }
#include "Base.hpp"

struct DerivedA : Base
{
    static Registrar<DerivedA> registrar;
    /* ... */
};
#include "DerivedA.hpp"
Registrar<DerivedA> DerivedA::registrar("My First Class");
#包括“DerivedA.hpp”
登记员德里维达:登记员(“我的第一堂课”);

现在,在
main()
启动后的任何时候,您都可以调用
Base::registry()
,以获取对每个派生类包含一个元素的映射的引用。

只需将派生类的名称键入用于初始化列表框的某个列表中即可?如果你想在运行时这样做,它是不可行的,C++没有反射。“很明显,所需的信息是在app中的某个地方。”为什么这么明显?这甚至不是真的。C++没有定义一个类如何在一个可执行文件中表示,而仅仅是一个例子,优化器可以登记所有的内容,因此在可执行文件中没有任何东西表明源是使用类的。好,我可以用类型化的方法来做:在编译时编译器将注册、填充列表框等,检索类型(类)。使用类的静态函数。但是我必须首先完成这个列表,而不是使用exe文件中的信息来实现一些神奇的功能。这是一个不错的解决方案,但是
#include
应该是
#include
,在某种程度上,如果你想按照自己的方式来做(就像Kerrek的回答那样)。真正的问题是,是否可行,因为标准C++不会为你做这件事。您仍然需要“手动”构建列表,因为每个类都需要代码来将自己添加到列表中;您只是让每个类将自己添加到列表中,而不是遍历并查找类。