我目前正在处理一个类,以及从这个基类派生出来的其他三个类。基类本质上应该是抽象的,因此我可以调用基类的虚拟函数,并让它执行派生类的预期函数。我的最终目标是做这样的事情:
class Car {
public:
virtual void drive() = 0; // Pure-virtual function
};
class Ford : public Car {
public:
virtual void drive() { std::cout << "driving Ford\n"; }
};这应该能行。在空文件中,此设置可以工作。我的实现肯定是错误的,但是c++编译器并没有给我任何关于错误是什么的好提示。
目前,我正在使用一个函数来创建派生类,返回要在main中使用的基类。我已经试过了所有我能想到的:
<代码>F 210的取消引用的基类指针
我只是无法让它为我的生命工作。当从基类变量运行时,虚拟函数只会导致seg错误。下面是我认为与当前状态相关的所有代码,因为我正在测试。
H:
class Instruction {
public:
virtual void print(){};
bool operator==(const int& rhs) const;
void writeBack();
void memory();
virtual void execute(long registers[32], long dmem[32]){};
unsigned int str2int(const char *str, int h);
virtual ~Instruction(){};
};ITypeInstruction.h:
class IType: public Instruction {
private:
int op;
string label;
string rs;
string rt;
string immediate;
map<string, string> registerMap;
public:
IType(int op, string label);
IType(int op, string label, string rs, string rt, string immediate, map<string, string> registerMap);
virtual void print();
void execute(long registers[32], long dmem[32]);
};ITypeInstruction.cpp:
void IType::print()
{
cout << "Instruction Type: I " << endl;
cout << "Operation: " << label << endl;
cout << "Rs: " << registerMap[rs] << " (R" << rs << ")" << endl;
cout << "Rt: " << registerMap[rt] << " (R" << rt << ")" << endl;
cout << "Immediate: 0x" << immediate << endl;
}Decode.cpp:
Instruction *decode(string binaryIn, map<string, string> registerSet, map<string, string> instructionSet, Instruction *instructionPointer)
{
IType ins = IType(opcode, label, rs, rt, imm, registerSet);
Instruction i = IType(opcode, label, rs, rt, imm, registerSet);
ins.print();
*instructionPointer = ins;
(*instructionPointer).print();
return instructionPointer;
}main.cpp
Instruction *instructionToExecute;
instructionToExecute = decode(instructionToDecode, registerSet, instructionSet, instructionToExecute);
instructionToExecute->print();发布于 2021-04-09 03:05:44
您显示的代码有多个问题。
一个是尝试取消对未初始化的instructionPointer变量的引用。
另一个原因是*instructionPointer = ins;导致了。
相反,动态创建IType对象并返回指向该对象的指针:
Instruction *decode(string binaryIn, map<string, string> registerSet, map<string, string> instructionSet)
{
return new IType(opcode, label, rs, rt, imm, registerSet);
}请注意,instructionPointer参数不再存在。
发布于 2021-04-09 03:08:14
在decode中,您将IType作为局部变量创建,在函数返回时导致它被销毁。
更多的C++风格
std::unique_ptr<Instruction>
decode(string binaryIn, map<string, string> registerSet, map<string, string> instructionSet)
{
std::unique_ptr<Instruction> ins = std::make_unique<IType>(opcode, label, rs, rt, imm, registerSet);
ins->print();
return ins;
}
auto instructionToExecute = decode(...);
instructionToExecute->print();发布于 2021-04-09 03:17:49
正确的方法是:
#include <memory>
std::unique_ptr<Instruction> decode(
string binaryIn,
map<string, string> registerSet,
map<string, string> instructionSet,
Instruction *instructionPointer)
{
return std::make_unique<IType>(opcode, label, rs, rt, imm, registerSet);
}
int main() {
// ...
auto instructionToExecute = decode(instructionToDecode, registerSet,
instructionSet, instructionToExecute);
instructionToExecute->print();
}正在发生的事情:函数中定义的变量(未标记为static)除了返回值外,不存在于该函数的末尾。您知道基类返回类型应该是指针,而不是基类类型,以避免切片,但随后需要某种方法来提供指向足以使用的对象的指针。std::make_unique是最简单的方法。
出了差错的事情:
Instruction *decode(string binaryIn, map<string, string> registerSet, map<string, string> instructionSet, Instruction *instructionPointer)
{
// OK, but the object "ins" lives only until the function returns.
IType ins = IType(opcode, label, rs, rt, imm, registerSet);
// Immediately slices to the base class, and isn't an IType any more.
Instruction i = IType(opcode, label, rs, rt, imm, registerSet);
// No problem.
ins.print();
// This uses the operator= of the base class Instruction.
// It's probably not going to be able to handle assigning derived info
// well, even if instructionPointer does in fact point at the same
// derived type.
*instructionPointer = ins;
(*instructionPointer).print();
// This will be just the same pointer as the passed argument,
// so doesn't really add any utility.
return instructionPointer;
}
int main() {
// ...
// This pointer is an uninitialized value. Using it is as bad as
// using the value of an uninitialized "int v;"...
Instruction *instructionToExecute;
// Uh oh. decode does *instructionToExecute = something;
// But instructionToExecute is uninitialized and doesn't actually
// point at any object to reassign! (Not even a base type object.)
instructionToExecute = decode(instructionToDecode, registerSet,
instructionSet, instructionToExecute);https://stackoverflow.com/questions/67014470
复制相似问题