C++ - 未正确调用覆盖方法(内存冲突)
C++ - Overriden method not called properly (memory violation)
在我的程序中,我试图创建名为“DMA”的抽象 class,“BaseDMA”从它继承。然后 classes "LacksDMA" 和 "HasDMA" 继承自 "BaseDMA"。
每个 class 覆盖方法
readInfo()
来自“DMA”。这是代码:
dma.h
#ifndef DMA_H_
#define DMA_H_
#include <iostream>
class DMA
{
protected:
char * label;
public:
DMA(const char * l);
DMA & operator=(const DMA & anotherDMA);
virtual ~DMA();
virtual void readInfo() const = 0;
char * getLabel() const ;
};
class BaseDMA: public DMA
{
private:
int rating;
public:
BaseDMA(const char * l, int r = 0);
BaseDMA(const BaseDMA & anotherBaseDMA);
virtual ~BaseDMA();
BaseDMA & operator=(const BaseDMA & anotherBaseDMA);
void readInfo() const override;
};
class LacksDMA: public BaseDMA
{
private:
enum { COL_LEN = 40 };
char color[COL_LEN];
public:
LacksDMA(const char * c = "no color", const char * l = "no color", int r = 0);
LacksDMA(const LacksDMA & anotherLacksDMA);
LacksDMA & operator=(const LacksDMA & anotherLacksDMA);
void readInfo() const override;
};
class HasDMA: public BaseDMA
{
private:
char * style;
public:
HasDMA(const char * s = "lack", const char * l = "lack", int r = 0);
HasDMA(const HasDMA & anotherHasDMA);
~HasDMA();
HasDMA & operator=(const HasDMA & anotherHasDMA);
void readInfo() const override;
};
#endif DMA_H_
dma.cpp
#include <string.h>
DMA::DMA(const char * l)
{
this->label = new char[strlen(l)+1];
strcpy(this->label, l);
}
DMA & DMA::operator=(const DMA & anotherDMA)
{
if(this == &anotherDMA)
return * this;
delete [] this->label;
this->label = new char[strlen(anotherDMA.label)+1];
strcpy(this->label, anotherDMA.label);
return *this;
}
char * DMA::getLabel() const
{
return this->getLabel();
}
DMA::~DMA()
{
delete [] label;
}
BaseDMA::BaseDMA(const char * l, int r)
: DMA(l)
{
this->rating = r;
}
BaseDMA::BaseDMA( const BaseDMA & anotherBaseDMA)
: DMA(anotherBaseDMA.label)
{
this->rating = anotherBaseDMA.rating;
}
BaseDMA::~BaseDMA()
{
}
BaseDMA & BaseDMA::operator=(const BaseDMA & anotherBaseDMA)
{
if(this == &anotherBaseDMA)
return *this;
DMA::operator=(anotherBaseDMA);
this->rating = anotherBaseDMA.rating;
return *this;
}
void BaseDMA::readInfo() const
{
std::cout << "BaseDMA object:\n";
std::cout << "Label: " << this->getLabel() << std::endl;
std::cout << "Rating: " << this->rating << std::endl;
}
LacksDMA::LacksDMA(const char * c, const char * l, int r)
:BaseDMA(l,r)
{
strcpy(this->color, c);
}
LacksDMA::LacksDMA(const LacksDMA & anotherLacksDMA)
: BaseDMA(anotherLacksDMA)
{
strcpy(this->color, anotherLacksDMA.color);
}
LacksDMA & LacksDMA::operator=(const LacksDMA & anotherLacksDMA)
{
if(this == &anotherLacksDMA)
return *this;
DMA::operator=(anotherLacksDMA);
strcpy(this->color, anotherLacksDMA.color);
return * this;
}
void LacksDMA::readInfo() const
{
BaseDMA::readInfo();
std::cout << "LacksDMA object:\n";
std::cout << "Color: " << color << std::endl;
}
HasDMA::HasDMA(const char * s, const char * l, int r)
:BaseDMA(l, r)
{
this->style = new char[strlen(s)+1];
strcpy(this->style, s);
}
HasDMA::HasDMA(const HasDMA & anotherHasDMA)
:BaseDMA(anotherHasDMA)
{
this->style = new char[strlen(anotherHasDMA.style)+1];
strcpy(this->style, anotherHasDMA.style);
}
HasDMA::~HasDMA()
{
delete [] this->style;
}
HasDMA & HasDMA::operator=(const HasDMA & anotherHasDMA)
{
if(this == &anotherHasDMA)
return *this;
BaseDMA::operator=(anotherHasDMA);
delete [] this->style;
this->style = new char[strlen(anotherHasDMA.style)+1];
strcpy(this->style, anotherHasDMA.style);
return *this;
}
void HasDMA::readInfo() const
{
BaseDMA::readInfo();
std::cout << "HasDMA object:\n";
std::cout << "Style: " << this->style << std::endl;
}
main.cpp
#include "dma.h"
void menuPanel();
void printDMS(DMA ** dms, int count);
int main()
{
const int DMA_COUNT = 4;
DMA * dmas[DMA_COUNT];
for(int i = 0; i < DMA_COUNT; i++)
{
void menuPanel();
int choice;
do
{
(std::cin >> choice).ignore();
if(std::cin.bad())
std::cin.clear();
} while (choice < 1 || choice > 3);
std::cout << "Write label: ";
char label[40];
std::cin.getline(label, 40);
std::cout << "Write rating: ";
int rating;
(std::cin >> rating).ignore();
if(choice == 1)
{
dmas[i] = new BaseDMA(label,rating);
std::cout << std::endl;
}
else if(choice == 2)
{
std::cout << "Write color: ";
char color[40];
std::cin.getline(color,40);
dmas[i] = new LacksDMA(color, label, rating);
}
else // choice == 3
{
std::cout << "write style: ";
char style[40];
std::cin.getline(style,40);
dmas[i] = new HasDMA(style, label, rating);
}
}
for(int i = 0; i < DMA_COUNT; i++)
delete dmas[i];
}
void menuPanel()
{
std::cout << "Panel action:\n";
std::cout << "1) make BbaseDMA" << std::endl;
std::cout << "2) make LacksDMA" << std::endl;
std::cout << "3) make HasDMA" << std::endl;
std::cout << std::endl;
}
void printDMS(DMA ** dms, int count)
{
for(int i = 0; i < count; i++)
{
dms[i]->readInfo();
std::cout << std::endl;
}
}
当我尝试通过调用 main()
中的 readInfo()
方法来使用运行时多态性时,我收到有关内存冲突的消息。
我做错了什么?
预先感谢您的回答。
您的代码有很多问题,但您的内存问题出在这里:
char * DMA::getLabel() const
{
return this->getLabel();
}
一旦调用 getLabel()
,例如在 BaseDMA::readInfo()
中,您将进入一个无限递归循环,最终溢出调用堆栈。
DMA::getLabel()
应该返回 this->label
而不是:
char * DMA::getLabel() const
{
return this->label;
}
在我的程序中,我试图创建名为“DMA”的抽象 class,“BaseDMA”从它继承。然后 classes "LacksDMA" 和 "HasDMA" 继承自 "BaseDMA"。
每个 class 覆盖方法
readInfo()
来自“DMA”。这是代码:
dma.h
#ifndef DMA_H_
#define DMA_H_
#include <iostream>
class DMA
{
protected:
char * label;
public:
DMA(const char * l);
DMA & operator=(const DMA & anotherDMA);
virtual ~DMA();
virtual void readInfo() const = 0;
char * getLabel() const ;
};
class BaseDMA: public DMA
{
private:
int rating;
public:
BaseDMA(const char * l, int r = 0);
BaseDMA(const BaseDMA & anotherBaseDMA);
virtual ~BaseDMA();
BaseDMA & operator=(const BaseDMA & anotherBaseDMA);
void readInfo() const override;
};
class LacksDMA: public BaseDMA
{
private:
enum { COL_LEN = 40 };
char color[COL_LEN];
public:
LacksDMA(const char * c = "no color", const char * l = "no color", int r = 0);
LacksDMA(const LacksDMA & anotherLacksDMA);
LacksDMA & operator=(const LacksDMA & anotherLacksDMA);
void readInfo() const override;
};
class HasDMA: public BaseDMA
{
private:
char * style;
public:
HasDMA(const char * s = "lack", const char * l = "lack", int r = 0);
HasDMA(const HasDMA & anotherHasDMA);
~HasDMA();
HasDMA & operator=(const HasDMA & anotherHasDMA);
void readInfo() const override;
};
#endif DMA_H_
dma.cpp
#include <string.h>
DMA::DMA(const char * l)
{
this->label = new char[strlen(l)+1];
strcpy(this->label, l);
}
DMA & DMA::operator=(const DMA & anotherDMA)
{
if(this == &anotherDMA)
return * this;
delete [] this->label;
this->label = new char[strlen(anotherDMA.label)+1];
strcpy(this->label, anotherDMA.label);
return *this;
}
char * DMA::getLabel() const
{
return this->getLabel();
}
DMA::~DMA()
{
delete [] label;
}
BaseDMA::BaseDMA(const char * l, int r)
: DMA(l)
{
this->rating = r;
}
BaseDMA::BaseDMA( const BaseDMA & anotherBaseDMA)
: DMA(anotherBaseDMA.label)
{
this->rating = anotherBaseDMA.rating;
}
BaseDMA::~BaseDMA()
{
}
BaseDMA & BaseDMA::operator=(const BaseDMA & anotherBaseDMA)
{
if(this == &anotherBaseDMA)
return *this;
DMA::operator=(anotherBaseDMA);
this->rating = anotherBaseDMA.rating;
return *this;
}
void BaseDMA::readInfo() const
{
std::cout << "BaseDMA object:\n";
std::cout << "Label: " << this->getLabel() << std::endl;
std::cout << "Rating: " << this->rating << std::endl;
}
LacksDMA::LacksDMA(const char * c, const char * l, int r)
:BaseDMA(l,r)
{
strcpy(this->color, c);
}
LacksDMA::LacksDMA(const LacksDMA & anotherLacksDMA)
: BaseDMA(anotherLacksDMA)
{
strcpy(this->color, anotherLacksDMA.color);
}
LacksDMA & LacksDMA::operator=(const LacksDMA & anotherLacksDMA)
{
if(this == &anotherLacksDMA)
return *this;
DMA::operator=(anotherLacksDMA);
strcpy(this->color, anotherLacksDMA.color);
return * this;
}
void LacksDMA::readInfo() const
{
BaseDMA::readInfo();
std::cout << "LacksDMA object:\n";
std::cout << "Color: " << color << std::endl;
}
HasDMA::HasDMA(const char * s, const char * l, int r)
:BaseDMA(l, r)
{
this->style = new char[strlen(s)+1];
strcpy(this->style, s);
}
HasDMA::HasDMA(const HasDMA & anotherHasDMA)
:BaseDMA(anotherHasDMA)
{
this->style = new char[strlen(anotherHasDMA.style)+1];
strcpy(this->style, anotherHasDMA.style);
}
HasDMA::~HasDMA()
{
delete [] this->style;
}
HasDMA & HasDMA::operator=(const HasDMA & anotherHasDMA)
{
if(this == &anotherHasDMA)
return *this;
BaseDMA::operator=(anotherHasDMA);
delete [] this->style;
this->style = new char[strlen(anotherHasDMA.style)+1];
strcpy(this->style, anotherHasDMA.style);
return *this;
}
void HasDMA::readInfo() const
{
BaseDMA::readInfo();
std::cout << "HasDMA object:\n";
std::cout << "Style: " << this->style << std::endl;
}
main.cpp
#include "dma.h"
void menuPanel();
void printDMS(DMA ** dms, int count);
int main()
{
const int DMA_COUNT = 4;
DMA * dmas[DMA_COUNT];
for(int i = 0; i < DMA_COUNT; i++)
{
void menuPanel();
int choice;
do
{
(std::cin >> choice).ignore();
if(std::cin.bad())
std::cin.clear();
} while (choice < 1 || choice > 3);
std::cout << "Write label: ";
char label[40];
std::cin.getline(label, 40);
std::cout << "Write rating: ";
int rating;
(std::cin >> rating).ignore();
if(choice == 1)
{
dmas[i] = new BaseDMA(label,rating);
std::cout << std::endl;
}
else if(choice == 2)
{
std::cout << "Write color: ";
char color[40];
std::cin.getline(color,40);
dmas[i] = new LacksDMA(color, label, rating);
}
else // choice == 3
{
std::cout << "write style: ";
char style[40];
std::cin.getline(style,40);
dmas[i] = new HasDMA(style, label, rating);
}
}
for(int i = 0; i < DMA_COUNT; i++)
delete dmas[i];
}
void menuPanel()
{
std::cout << "Panel action:\n";
std::cout << "1) make BbaseDMA" << std::endl;
std::cout << "2) make LacksDMA" << std::endl;
std::cout << "3) make HasDMA" << std::endl;
std::cout << std::endl;
}
void printDMS(DMA ** dms, int count)
{
for(int i = 0; i < count; i++)
{
dms[i]->readInfo();
std::cout << std::endl;
}
}
当我尝试通过调用 main()
中的 readInfo()
方法来使用运行时多态性时,我收到有关内存冲突的消息。
我做错了什么?
预先感谢您的回答。
您的代码有很多问题,但您的内存问题出在这里:
char * DMA::getLabel() const
{
return this->getLabel();
}
一旦调用 getLabel()
,例如在 BaseDMA::readInfo()
中,您将进入一个无限递归循环,最终溢出调用堆栈。
DMA::getLabel()
应该返回 this->label
而不是:
char * DMA::getLabel() const
{
return this->label;
}