正确执行动态铸造
Correctly perform dynamic cast
在子类中设置变量时,我试图弄清楚如何正确地派生多态类中的变量。经过一些帮助,我发现我需要在指针上使用dynamic_cast来正确访问我需要的信息。我在这方面遇到了一些麻烦。
这是我目前正在做的功能。
void translateLines(Parser parser, Code code)
{
while(parser.hasMoreCommands())
{
vector<Command>::const_iterator it = parser.currentCommand();
if(it->commandType() == "A")
{
//SubType* item = dynamic_cast<SubType*>(*the_iterator);
A_COMMAND* a_command = dynamic_cast<A_COMMAND*>(*it); //line that is throwing the error
//string symbol = a_command->get_symbol();
//cout << "symbol: " << symbol << endl;
//perform binary conversion
}
/*else if(command.commandType() == "C")
{
string dest = command.get_dest();
}*/
//shouldn't be any L commands in symbol-less version
else
{
std::cout << "unexpected command value n";
}
parser.advance();
}
}
这是我的Parser.h,它有关于向量迭代器的相关信息。
#include "Command.h"
#include <vector>
class Parser {
private:
std::vector<Command> commands;
std::vector<Command>::const_iterator command_it = commands.begin();
public:
Parser(std::vector<std::string>);
bool hasMoreCommands() //are there more commands in the input?
{
if(command_it != commands.end())
return true;
else
return false;
}
void advance(){std::next(command_it);} //move to next command, should only work if hasMoreCommands returns false}
std::vector<Command>::const_iterator currentCommand(){return command_it;}
std::vector<std::string> translateCommands(); //convert commands into binary strings
};
这是我收到的错误:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -o Assembler.o "..\Assembler.cpp"
..Assembler.cpp: In function 'void translateLines(Parser, Code)':
..Assembler.cpp:32:55: error: cannot dynamic_cast 'it.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator*<Command*, std::vector<Command> >()' (of type 'class Command') to type 'class A_COMMAND*' (source is not a pointer)
A_COMMAND* a_command = dynamic_cast<A_COMMAND*>(*it);
^
知道这里出了什么问题吗?
编辑:所以我现在明白了,我不能使用命令向量,而是需要指向命令的指针。我已经将Parser.h更改为处理vector<Command*>
而不是vector<Command>
。对于输入,我尝试了这样的东西:
A_COMMAND command();
commands.push_back(&command);
但这对我来说并不太有效,因为向量需要指针而不是引用。创建指向内存的指针并将其推入向量的最简单方法是什么?
您的vector
为Command
s。您不能将Command
强制转换为A_COMMAND*
。需要注意的是,vector<Command>
不可能包含A_COMMAND
。如果您想在C++中进行运行时多态性,必须使用指针或引用。在这种情况下,您的Parser::commands
需要是std::vector<Command*>
(或某种类型的智能指针,如std::vector<std::shared_ptr<Command>>
)。
以这个代码为例:
std::vector<Command> commands;
A_COMMAND a_command;
commands.push_back(a_command);
commands
不包含A_COMMAND
对象。它包含一个Command
对象,该对象是a_command
的副本。这或多或少是模棱两可的:
std::vector<Command> commands;
A_COMMAND a_command;
Command temp(a_command);
commands.push_back(temp);
记住,在C++中,变量是一个对象,而不是像其他一些语言(例如Java或C#)中那样引用对象。对象永远不会改变类型,但您可以有一个指向派生类型对象的引用或指针:
std::vector<Command*> commands;
A_COMMAND a_command;
commands.push_back(&a_command);
在这种情况下,commands[0]
是Command*
,但它指向一个A_COMMAND
对象。
重新编辑:
您正在添加一个指针。&some_variable
返回一个指向some_variable
的指针,但你绝对不应该做这样的事情。一旦command
超出范围,它就会被销毁,对它的任何访问都将导致未定义的行为。您需要在new
中使用动态内存分配。最好使用像std::shared_ptr<Command>
这样的智能指针类来保存动态分配的对象,这样以后就不必担心delete
会调用它们。
如果你使用原始指针,那么这样的东西就会起作用:
A_COMMAND* command = new A_COMMAND;
commands.push_back(command);
如果你采用这种方法,当你完成所有命令时,你需要delete
(可能是Parser
的析构函数):
for(Command* command : commands) {
delete command;
}
不过最好使用std::shared_ptr
s。将commands
声明为std::vector<std::shared_ptr<Command>> commands;
,然后:
std::shared_ptr<A_COMMAND> command = std::make_shared<A_COMMAND>();
commands.push_back(command);
然后,当对象的最后一个shared_ptr
超出范围时,它们都将自动获得delete
ed。如果你使用智能指针,你需要稍微改变它们的投射方式。查看std::dynamic_pointer_cast
。
try(it)而不是(*it)迭代器应该是指向对象allready的指针,因此需要省略*,因为这将导致实际数据而不是引用
- 以下代码执行哪种内存分配(动态或静态)?
- 释放动态分配的内存时是否需要执行此额外步骤
- 如果包含映射的静态库与可执行文件和动态库链接,静态映射(变量)是否会被多次释放?
- 从 C 可执行文件加载动态库时收到错误C++"undefined symbol"
- 调用函数一次用于动态链接库,一次从可执行文件调用函数
- 自上而下的动态规划与递归朴素解决方案.检查运行时执行
- 如果我在 Linux 上更改C++动态共享库,而我的可执行程序在其上使用,会发生什么
- 动态控制C++的执行策略类型
- 在动态加载的位置无关的可执行文件中分离错误
- C++模板的对象代码是否在可执行文件和动态库中重复?
- 为什么在 C++ 执行删除操作后仍可以访问释放的动态分配的内存
- 动态执行的 ARM ASM 系统调用,可从C++重新定位
- 如何动态执行具有任意参数类型的函数指针
- LDD可执行OUPUT中没有动态加载库
- 如何在C 中创建动态数组,该数组将在执行时决定其大小
- 为什么泄漏内存比在动态数组上执行 delete[] 慢
- 当使用rpath时,C++可执行文件无法找到动态链接的共享库
- 将静态和动态库链接到同一个可执行文件会导致哪些问题
- Qt C++,点击 QPushButton 时动态执行的操作
- 在Windows 8 (c++或.net / c#)的WinRT上动态执行代码