我有一个std ::基类指针列表,所有这些指针指向两个派生对象类中的一个。永远不会声明基类的实例,虽然基类不是抽象的,但每个成员函数都声明为虚拟。请考虑以下代码:
class A
{
public:
A();
...
//member functions
...
protected:
int common_data_1;
std::string common_data_2;
...
};
class B: public A
{
public:
B();
//member functions
...
protected:
std::string class_B_specific_data;
...
};
class C: public A
{
public:
C();
//member functions
...
protected:
std::string class_C_specific_data;
...
};
这些类通过条件语句实例化为适当的基类,并在同一代码块中同时由基类指针存储在std :: list中,如下所示:
std::list<A*> ptrList;
//conditional statements either create a B or C object
//and then that object is appended to the list
if (blahblah = true)
A* entry = new B();
else
A* entry = new C();
ptrList.append(entry);
我需要根据两个派生类继承的整数值对这个基类指针容器执行插入排序。但是,在我以前的尝试和使用调试器工具检查时,我发现我的插入排序算法在访问比较基于的整数时正确地进行了正确的比较,但是我无法交换位置std :: list中的基类指针。我想对这个指针容器进行排序,这样我就可以通过一个简单的for循环轻松地以正确的顺序打印数据。
这显然是对指针语义的误解的结果,但是为了获得很多好处,我无法找到任何阐明或解决我遇到的问题的参考或示例。
我在本网站或其他地方找到的任何结果都通过使用实际对象的容器而不是指向对象的指针容器来解决此问题。但是,就我而言,我无法做到这一点,因为我的代码依赖于基类的多态行为,以便拥有一个大的派生对象列表,而不是每个派生对象的多个列表。显然,这使得调用正确派生类的成员函数非常容易,如果可以避免,我宁愿不重新设计数据的整个结构。
如果需要,我可以发布我的代码片段和/或我在容器内正确交换这些指针位置所做的尝试;但是,我不确定这是否有用,因为我显然使用错误的语法来处理指针。
我感谢任何反馈;过去几周这个问题一直困扰着我,现在是时候退后一步寻求帮助了。我有一种感觉,我过度分析了这个问题,这很可能是阻止我解决问题的原因。
答案 0 :(得分:0)
假设您的目标是对现有容器进行排序,sort
有一个Compare comp
参数,允许您更改其默认行为。要使用它,您需要定义一个函数(一个覆盖operator()
的类),它知道您希望如何比较指针。在这种情况下,您希望定义一个比较指向对象所具有的common_data_1
。
class Comparator {
public:
bool operator(A* left, A* right) {
//You can do whatever logic you need here, here's an example:
return (a->common_data_1) < (b->common_data_2);
}
}
然后,在列表中拨打sort
:
ptrList.sort(Comparator());
答案 1 :(得分:0)
我喜欢@ IanPudney的答案,尽管我通常使用lambda:
ptrList.sort([](A* first, A* second)
{return first->common_data_1 < second->common_data_1;}
);
将common_data_1
替换为您要用于排序的数据成员或函数。