对于我来说,我根本无法理解为什么这个程序会出现段错误。问题是它检索 vector 容器中的对象使用菜单类中的函数使用 get_command() 并且由于某种原因在逐行测试主要函数后导致段错误:
menu->get_command()->execute();
我已经尝试更改语法以创建一个新的命令对象来存储从 get_command() 返回的对象并将索引更改为 0 和 -1 之间的值,但仍然没有修复错误。我至少花了几个小时试图找出原因,但似乎找不到解决方案。
class Base {
public:
/* Constructors */
Base() { };
/* Pure Virtual Functions */
virtual double evaluate() = 0;
virtual std::string stringify() = 0;
};
class op : public Base
{
public:
op() { };
op(double op1) { operand = op1; }
double evaluate() { return operand; }
string stringify() {
string value = to_string(operand);
return value;
}
private:
double operand;
};
class Command {
protected:
Base* root;
public:
Command() { this->root = nullptr; }
double execute() { return root->evaluate(); }
std::string stringify() { return root->stringify(); }
Base* get_root() { return root; }
};
class Menu {
private:
int history_index; // Indexes which command was last executed, accounting for undo and redo functions
std::vector<Command*> history; // Holds all the commands that have been executed until now
public:
Menu() {
// Constructor which initializes the internal members
history_index = -1;
}
std::string execute() {
// Returns the string converted evaluation of the current command
return to_string(history[history_index - 1]->execute());
}
std::string stringify() {
// Returns the stringified version of the current command
return history[history_index]->stringify();
}
bool initialized() {
// Returns if the history has an InitialCommand, which is necessary to start the calculation
if (history[history_index] != nullptr)
return true;
else
return false;
}
void add_command(Command* cmd) {
// Adds a command to the history (does not execute it), this may require removal of some other commands depending on where history_index is
history.push_back(cmd);
history_index++;
}
Command* get_command() {
// Returns the command that the history_index is currently referring to
return history[history_index];
}
void undo() {
// Move back one command (does not execute it) if there is a command to undo
history_index--;
}
void redo() {
// Moves forward one command (does not execute it) if there is a command to redo
history_index++;
}
};
class InitialCommand : public Command {
protected:
Base* root;
public:
InitialCommand(Base* b) { this->root = b; }
double execute() { return root->evaluate(); }
std::string stringify() { return root->stringify(); }
Base* get_root() { return root; }
};
void main()
{
Menu* menu = new Menu();
InitialCommand* temp = new InitialCommand(new op(7));
menu->add_command(temp);
EXPECT_EQ(menu->get_command()->execute(), 7);
system("PAUSE");
}
最佳答案
您没有正确执行继承,因为您在 Command
和 InitialCommand
之间复制导致错误的字段。
两个命令类都有一个 Base *root
成员和非虚拟的 execute
方法。当您构造一个新的 InitialCommand
对象时,InitialCommand::root
对象指向为它创建的 op
,而 Command::root
保持 NULL
因为 Command
的默认构造函数。然后,当您调用 menu->get_command()
时,它会调用 Command::execute
因为 execute
是非虚拟的并且 menu
是一个 Command *
。 Command::execute
将取消引用 NULL root
,导致您的段错误。
从 InitialCommand
中移除 Base *root
成员,并将参数传递给 Command
中的构造函数。您可能希望将一些方法(例如 execute
)设为虚拟。
关于c++ - 为什么我的代码出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56385271/