Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.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++_Struct_Downcast - Fatal编程技术网

C++ C++;向下投射结构

C++ C++;向下投射结构,c++,struct,downcast,C++,Struct,Downcast,我有以下代码: struct Operation { public : OperationName name; }; struct FilterOperation : Operation { FilterName filter; std::list<std::string> params; }; struct操作{ 公众: 操作名称; }; 结构过滤器操作:操作{ 过滤器名称过滤器; std::列表参数; }; OperationName

我有以下代码:

struct Operation {
    public :
        OperationName name;
};

struct FilterOperation : Operation {
    FilterName filter;
    std::list<std::string> params;
};
struct操作{
公众:
操作名称;
};
结构过滤器操作:操作{
过滤器名称过滤器;
std::列表参数;
};
OperationName和FilterName是列出每个操作和筛选器的所有不同名称的枚举

在遍历所有操作的for each循环中,我想将一个操作向下转换为FilterOperation:

std::list<Operation> operations
for (Operation op : operations) {
switch (op.name) {
    case o_filter :
        std::cout  << dynamic_cast<FilterOperation*>(&op)->filter << std::endl;
    }
}
std::列表操作
用于(操作op:操作){
开关(op.name){
案例o_过滤器:

std::cout filter这是未定义的行为

op
是一个
操作
。不是指向
操作
的指针或引用,小于
过滤操作
。因此
&op
显然不是
过滤操作*

从cppreference.com下载:

dynamic\u cast(表达式)
如果强制转换成功,则dynamic_cast返回类型为new_type的值。如果强制转换失败且new_type为指针类型,则返回该类型的空指针


很明显,
dynamic\u cast(&op)
是一个空指针,取消引用它是UB。

关于添加虚拟函数的直觉应该为您解决了编译器错误。您确定没有遇到其他错误吗

在任何情况下,因为您处理的是对象的实例而不是指针,所以这永远不会起作用。您的列表由操作对象组成,而不是FilterOperation对象。如果要插入FilterOperation对象,则需要一个指针列表(最好是shared_ptr),而不是按值存储:

std::list<Operation*> operations
for (Operation* op : operations) {
switch (op->name) {
    case o_filter :
        std::cout  << dynamic_cast<FilterOperation*>(op)->filter << std::endl;
    }
}
std::列表操作
用于(操作*op:操作){
开关(操作->名称){
案例o_过滤器:

std::cout filter使用stl容器您可以使用
操作的复制构造函数和
操作符=
。 这些方法仅从
过滤器操作
复制
操作
,而不是复制整个结构

要解决此问题,您应该使用
std::list
或者更好的方法,
std::list
而不是
std::list

这样,您就不会将操作复制到列表中,只需将指针


此外,必须将虚拟析构函数添加到
操作
结构中,否则会出现内存泄漏,因为派生类中的列表(
过滤器操作
)当你删除一个
操作时不会被释放,但是-你有一个操作列表;它们不是filteroperations。即使它们基于filter操作,你也会对它们进行切片并丢失任何基于它们的filter对象。你能在操作对象列表中首先存储FilterOperation对象吗?我想st接受基类型,但也可以接受子结构,我可以更改列表以实现此行为吗?@jszpilewski:嗯,编译器没有抱怨这个:filterooperation op;operations.push_back(op);Im打开枚举值,而不是字符串您应该添加一个测试,测试动态_强制转换是否返回
nullptr
,因为取消引用它是正确的UB@SergeBallesta是的,但我不想用与Estefull试图理解的内容没有直接关系的东西混淆答案。我认为他们的混淆源于不理解对象sli在C++中,它们可能来自java/.NET背景。知道检查Null pTR不是问题。好的,但是你至少应该在你的帖子中附加一条线。我同意这不是问题,但是你的代码不能因为UB直接使用。
dynamic_cast < new_type > ( expression )      
std::list<Operation*> operations
for (Operation* op : operations) {
switch (op->name) {
    case o_filter :
        std::cout  << dynamic_cast<FilterOperation*>(op)->filter << std::endl;
    }
}