Setting a variable in a child class中,我试图弄清楚如何正确地导出多态类中的变量。经过一番帮助,我发现我需要在指针上使用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);


但这对我来说不是很有效,因为向量需要指针而不是引用。创建指向内存的指针并将其推入向量的最简单方法是什么?

最佳答案

您有一个vectorCommand个。您不能将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。将commands声明为std::vector<std::shared_ptr<Command>> commands;,然后:

std::shared_ptr<A_COMMAND> command = std::make_shared<A_COMMAND>();
commands.push_back(command);


然后,当对象的最后一个delete超出范围时,所有对象将自动被shared_ptr识别。如果使用智能指针,则需要将它们强制转换为稍有不同。调查std::dynamic_pointer_cast

关于c++ - 正确执行动态转换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36254484/

10-17 02:03