代码的工作方式是有一个名为“Module”的基本纯虚拟类,其子类为“Living”,“Manufacturing”和“PowerGen”,它使用了一些虚函数。在主驱动程序文件中,我成功地从文件中读取模块列表并将它们存储在模块指针的向量中。当我想使用虚拟显示功能来显示矢量元素的模块细节时,就会出现问题。我遇到了分段错误。任何帮助将不胜感激!
Class Module
{
public:
Module() = default;
explicit Module(const string& purpose, const string& id)
{
this->purpose = purpose;
this->id = id;
}
explicit Module(const string& purpose) { this->purpose = purpose; }
virtual ~Module() { }
virtual void setCrew( ) = 0;
virtual void display( ) const = 0;
void addCrew(const string& name)
{
crew_list.push_back(Crew(name));
++number_of_crew;
}
void setPowerReq(double power) { this->power = power; }
void setMaxCrew(int max_crew) { this->max_crew = max_crew; }
string getPurpose( ) { return purpose; }
string getId( ) { return id; }
int getNumberOfCrew( ) { return number_of_crew; }
int getMaxCrew( ) { return max_crew; }
double getPower( ) { return power; }
friend ostream& operator << ( ostream& os, const Module& m );
friend ofstream& operator << ( ofstream& os, const Module& m );
friend ifstream& operator >> ( ifstream& is, Module& m );
private:
string purpose = "unknown";
string id = "unknown";
int number_of_crew = 0;
int max_crew = 0;
double power = 0;
vector<Crew> crew_list;
};
class Living : public Module
{
public :
Living( ) = default;
explicit Living(const string& purpose);
Living(int meals, const string& id);
void setCrew( )
{
setMaxCrew( floor(meals / 3) );
setPowerReq( meals * 1.4 );
}
void display( ) const
{
cout << *this;
}
friend ofstream& operator << ( ofstream& os, const Living& l );
friend ifstream& operator >> ( ifstream& is, Living& l );
private :
int meals = 0;
static string type;
};
class Manufacturing : public Module
{
public:
Manufacturing( ) = default;
Manufacturing( const string& product, int quantity, const string& id );
explicit Manufacturing( const string& purpose );
void setCrew( )
{
setPowerReq( quantity * 6 );
setMaxCrew( maxCrew );
}
void display( ) const
{
cout << *this;
}
friend ofstream& operator << ( ofstream& os, const Manufacturing& m );
friend ifstream& operator >> ( ifstream& is, Manufacturing& m );
private:
static string type;
string product = "unknown";
static int maxCrew;
int quantity = 0;
};
class PowerGen : public Module
{
public:
PowerGen() = default;
PowerGen( int number_of_generators, const string& id );
explicit PowerGen( const string& purpose );
void setCrew( )
{
setMaxCrew(0);
setPowerReq( -(number_of_generators * 7) );
}
void display( ) const
{
cout << *this;
}
friend ofstream& operator << ( ofstream& os, const PowerGen& p );
friend ifstream& operator >> ( ifstream& is, PowerGen& p );
private:
static string type;
const int max_generators = 8;
int number_of_generators = 0;
};
与主驱动程序文件相关的部分,当调用时会导致分段错误:
if( cityVector.size() > 0 )
{
cout << "\nHere is the complete City" << endl;
for ( auto iter : cityVector )
{
iter->display( );
cout << endl << endl;
}
} else {
cout << "\nThere are no Modules in the City" << endl;
}
这是我从文件中加载数据的方式,其中VMOD = vector:
void load( VMOD & cityVector )
{
string filename;
cout << "Please enter a filename >> ";
getline( cin, filename );
ifstream fin;
fin.open(filename);
if (!fin.fail())
{
while ( !fin.eof() )
{
string purpose;
getline( fin, purpose );
if ( purpose == "Living" )
{
Living object(purpose);
loadObject( cityVector, object, fin );
} else if ( purpose == "Manufacturing" )
{
Manufacturing object(purpose);
loadObject( cityVector, object, fin );
} else if ( purpose == "Power Generation" )
{
PowerGen object(purpose);
loadObject( cityVector, object, fin );
} else {
}
}
cout << "The city has " << cityVector.size() << " modules!" << endl;
} else {
cout << "File does not exist... " << endl;
}
fin.close();
}
template<typename T>
void loadObject( VMOD & cityVector, T object, ifstream& fin )
{
fin >> object;
Module* mptr;
mptr = &object;
cityVector.push_back(mptr);
}
文件看起来像这样:
Living
L1
5
21
2
First Person
Fourth Person
15
Manufacturing
M1
10
12
4
Second Person
Third Person
Fifth Person
Sixth Person
C++ ness
2
Power Generation
P1
0
-14
0
2
答案 0 :(得分:0)
你有一个悬空指针问题。
template<typename T>
void loadObject( VMOD & cityVector, T object, ifstream& fin )
{
// object is a function local object
// since it is passed by value.
fin >> object;
Module* mptr;
// This is a pointer to a local object.
// It is invalid when the function returns.
mptr = &object;
// Storing a pointer that will be a dangling pointer as soon
// the function returns.
cityVector.push_back(mptr);
}
您需要为已还原的对象使用动态分配的内存,并将其保存在cityVector
。
完成使用后,您需要确保释放内存。
template<typename T>
void loadObject(VMOD& cityVector, ifstream& fin )
{
T* objectPtr = new T;
fin >> *objectPtr;
cityVector.push_back(objectPtr);
}
并使用以下语法调用它:
loadObject<LivingObject>(cityVector, fin);