我在尝试从抽象类
创建子类时遇到了问题class people
{
public:
people();
~people();
virtual int comparable(people*);
void order(people**,int);
};
我的子类
class worker : public people
{
private:
int salary;
public:
worker();
~worker();
int comparable (people*);
};
我需要按工资(来自工人)订购动态数组的人,但我无法匹配人数组[j] =工人a;
你建议什么? 然后我如何调用de function order?因为a无法创建人物对象
答案 0 :(得分:1)
提供纯虚函数来比较两个people
。
#include <algorithm>
#include <utility>
#include <stdexcept>
class people
{
public:
people();
~people();
virtual int compare(const people* rhs) const = 0;
};
在compare
中实施worker
功能。
class worker : public people
{
private:
int salary;
public:
worker();
~worker();
virtual int compare(const people* rhs) const
{
const worker* rhsw = dynamic_cast<const worker*>(rhs);
if ( NULL == rhsw )
{
throw std::invalid_argument("rhs");
}
return (this->salary - rhsw->salary);
}
};
提供可在std::sort
中使用的仿函数。
struct people_compare
{
bool operator()(people* lhs, people* rhs) const
{
return (lhs->compare(rhs) < 0);
}
};
使用std::sort
和上述仿函数对人员列表进行排序。
void order(people** plist, int num)
{
std::sort(plist, plist+num, people_compare());
}
答案 1 :(得分:0)
看起来似乎是一件相当奇怪的事情,如果你希望对某些salary
的集合进行排序,那么在people
中设置一个people
变量会更有意义。他们的薪水。
我还不清楚comparable
的返回值是什么,但这里是基于salary
进行排序的解决方案,并假设people
不属于worker
类型(或由此派生)的对象没有工资。它返回0表示相等的工资,1表示&#34;该对象的工资高于传入的对象&#34;和#34;工资少于在对象中传递的工资&#34;。
但请注意,这是一个非常糟糕的设计,您通常不应该像这样使用dyanamic_cast
。
int worker::comparable(people *p)
{
worker *w = dynamic_cast<worker*>(p);
int wsalary = 0;
if (w)
wsalary = w->salary;
if (salary == wsalary) return 0;
if (salary > wsalary) return 1;
return -1;
}
答案 2 :(得分:0)
如果你的数组包含人物实例,那么可能会发生其中一些实例实际上不是工作者实例(但是某些其他类的实例派生自人),在这种情况下,你不能按工资对数组进行排序,因为它不是保证所有数组项目实际上都有薪水。
好的,此时您可能想说在这种特殊情况下,您实际上保证所有人指针都是工作者实例。即使在这种情况下你的设计也很糟糕,因为如果你保证所有人指针都是工人类,那你为什么不对工作指针数组执行排序操作???
之前的解释表明,将比较操作作为虚方法放入基类并不是一个好主意,因为不同子类的实例之间的比较通常是未定义或无效的操作。
看看一些更高级别的语言。即使那些提供某种通用虚拟比较运算符的人也已经切换到某种通用/模板化解决方案,其中接口具有类型参数,因此比较接口是类型安全的,无需任何类型检查和向下转换。 (type_check + downcast == C ++中的dynamic_cast)。
如果您仍想在基类中使用常规虚方法解决问题,则必须按照Mats Petersson的推荐执行动态转换,并且您决定支持其他类(而不是当前类)(如果某人传入了一个不受支持的类的实例,您可能想要抛出异常。这很糟糕,原因很多。涉及dynamic_cast的C ++代码通常设计得不好,dynamic_cast是一个OOP反模式(就像它在类型检查后执行的向下转换...)。 dynamic_cast的另一个问题是使用dynamic_cast的糟糕设计经常将许多其他编译时错误转换为仅在某些特殊情况/情况下发生的运行时错误(通常在最终用户的机器上,不幸的是,取决于代码覆盖率)您的测试用例及其执行频率。)
答案 3 :(得分:0)
我需要按工资(来自工人)订购动态数组的人,但是[...]。你有什么建议?然后我如何调用函数
order
?
我考虑重构您的代码。对于动态数组,我会使用std::vector
,对于排序,您可以使用std::sort
。
如果你想要一个解耦系统,你应该移动&#34;容器并对特定代码进行排序&#34;远离person
和worker
类。
事实上,事实证明,在这种情况下,你甚至根本不需要基类或公共继承。您可以为层次结构的每个类定义比较函数。尤其适用于worker
:
bool compare(const worker &a, const worker &b) {
// return true if a is < b
// example follows
return a.salary < b.salary;
}
最后,你留下了:
class worker {
// ...
};
std::vector<worker> workers;
当您需要对workers
向量进行排序时,您可以执行以下操作:
std::sort(workers.begin(), workers.end(), compare);
如果能够做worker_a < worker_b
是有意义的(即使基于工资的歧视不是一个流行的观点),你可以实现operator<
:
struct worker {
bool operator<(const worker& rhs) {
// for example
return salary < rhs.salary
}
};
只需按:
排序std::sort(workers.begin(), workers.end());