【发布时间】:2021-03-17 15:32:02
【问题描述】:
我从敏捷软件开发中的 ch9 Open Closed Principle 中获取了示例代码,如下所示,它应该按照下面代码中表格 typeOrderTable 给出的顺序按优先级对形状进行排序。好吧,我确实必须添加一个主代码和测试代码,但几乎复制了本书的代码。但是输出显示它没有按照表格进行排序。而且如果我尝试调试代码,代码路径并没有进入Shape::Precedes函数。
我该如何解决这个问题?
代码:
#include <typeinfo>
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Shape {
public:
virtual void Draw() const = 0;
bool Precedes(const Shape& s) const;
bool operator<(const Shape& s) const {
return Precedes(s);
}
private:
static const char* typeOrderTable[];
};
bool Shape::Precedes(const Shape& s) const {
const char* thisType = typeid(*this).name();
const char* argType = typeid(s).name();
bool done{ false };
int thisOrd{ -1 };
int argOrd{ -1 };
for (int i = 0; !done; ++i) {
const char* tableEntry = typeOrderTable[i];
if (tableEntry != 0) {
if (strcmp(tableEntry, thisType) == 0)
thisOrd = i;
if (strcmp(tableEntry, argType) == 0)
argOrd = i;
if (argOrd >= 0 && thisOrd >= 0)
done = true;
}
else done = true;
}
return thisOrd < argOrd;
}
class Square : public Shape {
public:
virtual void Draw() const {
cout << "square\n";
}
};
class Circle : public Shape {
public:
virtual void Draw() const {
cout << "circle\n";
}
};
class Rectangle : public Shape {
public:
virtual void Draw() const {
std::cout << "rectangle\n";
}
};
const char* Shape::typeOrderTable[] = {
typeid(Circle).name(),
typeid(Rectangle).name(),
typeid(Square).name(),
0
};
void DrawAllShapes(vector<Shape*> shapes) {
vector<Shape*> orderedList = shapes;
sort(orderedList.begin(), orderedList.end());
for (auto shape : orderedList) {
shape->Draw();
}
}
int main() {
Shape* circle = new Circle();
Shape* square = new Square();
Shape* rectangle = new Rectangle();
Shape* rectangle2 = new Rectangle();
vector<Shape*> shapes{ rectangle, square, circle, rectangle2 };
DrawAllShapes(shapes);
/* should print:
circle
rectangle
rectangle
square
but instead prints:
rectangle
square
rectangle
circle
ie unsorted - actually it is random in the output
*/
}
【问题讨论】:
-
您的排序比较指针值(即地址),而不是指向的内容。您需要在排序调用中使用自定义比较器。
-
旁注:由于 C++11 不建议使用原始指针和手动管理内存。使用
std::unique_ptrgodbolt.org/z/Prbhdb
标签: c++ polymorphism overloading