如果我不使用然后删除基类Output
的指针,则此代码可以正常工作。调用Output的析构函数,似乎正常工作。我在这里错过了什么吗?
// multiple inheritance
// Testing overload of muliple inheritance of pure virtual functions.
#include <iostream>
#include <string>
using namespace std;
class Polygon {
protected:
int width, height;
public:
Polygon (int a, int b) : width(a), height(b) {}
~Polygon() = default;
virtual int area() = 0;
};
class Output {
private:
string* myString;
public:
Output() {
myString = nullptr;
}
Output(const string& s) {
myString = new string(s);
}
// This seems to work, but ther core dump happens right afterwards.
~Output() {
cout << "delete called with: " << myString << '\n';
if (myString != nullptr)
delete myString;
}
virtual int area() = 0;
void print () {
cout << *myString << this->area() << '\n';
}
};
class Rectangle: public Polygon, public Output {
public:
Rectangle (int a, int b) : Polygon(a,b), Output{"A Rectangle's area is: "} {}
int area () {
return width*height;
}
};
class Triangle: public Polygon, public Output {
public:
Triangle (int a, int b) : Polygon{a,b}, Output{"A Triangle's area is: "} {}
int area ()
{ return width*height/2; }
};
int main () {
Output * ptr1 = new Rectangle(4,5);
Output * ptr2 = new Triangle(4,5);
ptr1->print();
ptr2->print();
// Causes core dump.
delete ptr1;
delete ptr2;
return 0;
}
答案 0 :(得分:3)
此代码存在几个主要问题:
首先,您不应该为此使用多重继承。这完全是不必要的,并且将导致很难追踪错误。
其次,在删除指针之前,您不需要测试nullptr
- 它是多余的,因为delete
已经这样做了。
第三,你的基类都没有虚拟析构函数。 (您当前的错误)
第四,你违反了Output
课程中的Rule of 3(可能需要在所有课程中使用它)。
第五,假设string
表示std::string
。它没有理由成为string*
- 只需使用std::string
并避免分配和取消分配它。
我没有修复您的设计问题,但您的内存访问和多态问题已修复here。
#include <iostream>
#include <string>
using namespace std;
class Polygon
{
protected:
int width, height;
public:
Polygon (int a, int b) : width(a), height(b) {}
virtual ~Polygon() { } // needed!
virtual int area() = 0;
};
class Output
{
private:
std::string myString; // no need to be a pointer
public:
Output() { }
Output(const string& s) : myString(s) { }
virtual ~Output() { } // also needed!
virtual int area() = 0;
void print () {
cout << myString << this->area() << '\n';
}
};
class Rectangle: public Polygon, public Output
{
public:
Rectangle (int a, int b) : Polygon(a,b), Output{"A Rectangle's area is: "} {}
int area () {
return width*height;
}
};
class Triangle: public Polygon, public Output
{
public:
Triangle (int a, int b) : Polygon{a,b}, Output{"A Triangle's area is: "} {}
int area ()
{ return width*height/2; }
};
int main ()
{
Output * ptr1 = new Rectangle(4,5);
Output * ptr2 = new Triangle(4,5);
ptr1->print();
ptr2->print();
// Causes core dump.
delete ptr1;
delete ptr2;
return 0;
}
编辑:可以找到实现所需程序的更好方法的示例here。
答案 1 :(得分:2)
您的Output
和Polygon
类析构函数也应为virtual
:
class Output {
private:
std::string* myString;
public:
// ...
virtual ~Output() {
// ^^^^^^^
}
};
另请注意:您可以简单地使用std::string*
成员,而不是使用std::string myString;
指针:
private:
std::string myString;
并且在任何情况下都可以使new string()
和delete myString;
正确无误。