0

我想我在这里遇到了设计问题,非常感谢您的帮助。

我有一个代表基本算法的类 Base。

class BaseAlgo: public Algo<double>
{
public:

/// data structures
// ...
// 
 struct Item {
    double profit;
    double weight;
    double xjSolution;
 };

 typedef std::pair<double, std::vector<Item>::iterator> ScaledItem;

protected:

 std::vector<Item> & items_;
 boost::ptr_vector<ScaledItem> largeItems_;
}

BaseAlgo 有一些功能,其中一些是虚拟的,另一些则不是。

作为派生类,我有

class DerivedAlgo: public BaseAlgo
{
public:

/// enhanced data structures
// ...
// 

 struct DerivedScaledItem : ScaledItem {
    int additional;
 };
 }

在我在 DerivedAlgo 中重载的虚拟函数中,我需要访问 DerivedScaledItem 的附加参数,这不是多态性的初衷。是否有可能,或者您是否提出了不同的设计方法?我现在对任何事情都持开放态度,因为我完全被困住了。

现在,BaseAlgo 中的 largeItems_ 成员 ptr_vector 持有 ScaledItems(内部作为指针)。我想,我可以像这样使用它:

// in DerivedAlgo

void someMethod(std::vector<Item>::iterator someiterator){
   DerivedScaledItem doubledItem = {};

   doubledItem.first = 4.5;
   doubledItem.second = someiterator;
   doubledItem.additional= 2;
   largeItems_.push_back(new UnboundedScaledItem(doubledItem));
   boost::ptr_vector<DerivedScaledItem>::iterator it = largeItems_.begin();
   std::cout << "added large item " << *it << std::endl;
}

当我计算刚刚添加的对象时,additional 设置为 2。但之后,调用 largeItems_ 的 getter,附加字段将设置回 0,然后只设置 ScaledItem 中已知的两个字段。

// in BaseAlgo
const boost::ptr_vector<ScaledItem>& getLargeItems() const
{
    return largeItems_;
}

// from my test.cpp
DerivedAlgo obj;
// ... define someiterator
obj.someMethod(someiterator);
boost::ptr_vector<BaseAlgo::ScaledItem> largeItems = knapsack.getLargeItems();
boost::ptr_vector<DerivedAlgo::DerivedScaledItem>::iterator it = largeItems.begin();
std::cout << "read large item " << *it << std::endl;
4

1 回答 1

1

我猜你没有告诉 boost 如何克隆你的 ptr_vector-s 元素,如下所述:http: //www.boost.org/doc/libs/1_54_0/libs/ptr_container/doc/tutorial.html#cloneability

因此,在这一行中,您创建了向量的副本(您可以通过声明largeItems为引用来避免这种情况),它们通过 的构造函数被复制ScaledItem,这会丢失您的附加成员。

boost::ptr_vector<BaseAlgo::ScaledItem> largeItems = knapsack.getLargeItems();

关于您对另一种设计的问题:

  • 您可以将向量元素的类型作为模板参数传递给基类。
  • 您可以将向量移动到派生类中,并仅提供(虚拟、抽象)函数来访问基类中的单个元素。如果基类也应该能够创建元素,您可能需要某种工厂方法。因为您不想要向量中的基本元素类型。
于 2013-10-17T23:37:15.417 回答