我如何在模板中使用智能指针?

时间:2016-04-26 20:51:21

标签: c++ codeblocks dev-c++

我正在使用模板,但我有问题将我的餐厅项目中的食用或饮料转换为模板中的项目?有人知道怎么做吗? 饮料和食物都是从物品中继承而来的 或者如果有人有任何想法改进我的项目以获得任何帮助

#ifndef NODE_H
#define NODE_H
#include "Item.h"
#include "Edible.h"
#include "Beverage.h"
#include "Special.h"
enum Type { special ,beverage, edible };
template <class T>
class Node
{
    public:

        T* _item;
        Node* _next;
        int _refCount;
        Node():_next(NULL),_refCount(0),_item(NULL){}
        Node(T* item,Node<T>* next):_next(next),_item(item),_refCount(1){}
        ~Node(){    if(_item)delete _item;_item=NULL;}

        friend ostream& operator << (ostream& os,const Node<T>& node){    if(node._item)return  os<<*node._item;else return os<<"";}
        Node<T>*   getNode(int i);
        double getPrice()const {return _item->getPrice();}
        void addRefCount()  {_refCount++;}
        void addNode(Node<T>* newItem);
        void print();
        template<class newType> // template function for
        operator Node<newType>() // implicit conversion ops.
        {
            return Node<It>(this);
        }
        int removeItem(){return --_refCount;}
    private:
};

template <class T>
inline Node<T>*  Node<T>::getNode(int i)
{
    Node<T>* current=this;
    for(i;i>0;i--)
        current=current->_next;
    return current;
}

template <class T>
inline void Node<T>::addNode(Node<T>* newItem)
{
    if(newItem==NULL)
        return;
   newItem->_next=_next;
   _next=newItem;

}
template <class T>
inline void Node<T>::print()
{
    Node<T>* head=this;
    /*Print all item until we have null*/
    while(head!=NULL)
    {
        /*Check if there is any item inside*/
        if(head->_item!=NULL)
            cout<<*head->_item<<endl;
        head=head->_next;
    }
}

#endif // NODE_H

我对此功能有疑问:inline Node<T>* Node<T>::getNode(int i)

#include "Menue.h"

Menue::Menue():_headEdible(NULL), _headBeverage(NULL),_headSpecial(NULL)
{

}

void Menue::printMenue()
{

    _headEdible->print();
    _headBeverage->print();
    _headSpecial->print();

}


void Menue::deleteItem(Node<Edible> *item)
{
    if(item==NULL)
        return;
    if(!(item->removeItem()))
    {
        Node<Edible>* current;
        current=_headEdible;
        if(_headEdible==item)
            _headEdible=_headEdible->_next;
        else
        {
            while(current!=NULL&&item!=current->_next)
                current=current->_next;
            if(current==NULL)
                return;

            current->_next=current->_next->_next;
        }
        delete item;
    }
}


void Menue::deleteItem(Node<Beverage>*  item)
{
    if(item==NULL)
        return;
    if(!(item-> removeItem()))
    {
        Node<Beverage>* current=_headBeverage;
        if(_headBeverage==item)
            _headBeverage=_headBeverage->_next;
        else
        {
            while(current!=NULL&&item!=current->_next)
                current=current->_next;
            if(current==NULL)
                return;
            if(item!=current->_next)
                return;
            current->_next=current->_next->_next;
        }
        delete item;
    }
}

void Menue::deleteItem(Node<Special>*  item)
{
    if(item==NULL)
        return;
    if(!(item-> removeItem()))
    {
        Node<Special>* current=_headSpecial;
        if(_headSpecial==item)
            _headSpecial=_headSpecial->_next;
        else
        {
            while(current!=NULL&&item!=current->_next)
                current=current->_next;
            if(current==NULL)
                return;
            if(item!=current->_next)
                return;
            current->_next=current->_next->_next;
        }
        delete item;
    }
}






Menue::~Menue()
{
    while(_headEdible!=NULL)
        if(!(_headEdible->removeItem()))
        {
            Node<Edible>* temp=_headEdible->_next;
            delete _headEdible;
            _headEdible=temp;
        }
    while(_headBeverage!=NULL)
        if(!(_headBeverage->removeItem()))
        {
            Node<Beverage>* temp=_headBeverage->_next;
            delete _headBeverage;
            _headBeverage=temp;
        }
    while(_headSpecial!=NULL)
        if(!(_headSpecial->removeItem()))
        {
            Node<Special>* temp=_headSpecial->_next;
            delete _headSpecial;
            _headSpecial=temp;
        }
}
Node<Item>* Menue:: getItem(int i,Type type)
{
    /*Switch the correct item we want to order*/
    switch (type)
    {
        case special:return _headEdible->getNode(i);
        break;

        case beverage:return _headBeverage->getNode(i);
        break;

        case edible:return _headSpecial->getNode(i);
        break;

        default: return NULL;
        break;
    }

}

这是在manue中使用它的函数Node<Item>* Menue:: getItem(int i,Type type) 如果有人知道如何解决它?

1 个答案:

答案 0 :(得分:0)

Node<Item>* Menue:: getItem(int i,Type type)

无效,因为BeverageEdibleSpecial可能是Item的子类,Node<Item>Node<Beverage>不同。 Node<Edible>Node的专精,而不是Node<Item>的子类,不能用作Node<Item>

幸运的是,菜单的用户不应该关心那里隐藏有节点的链接列表。他们想要的只是一个Item,这可以在没有Node包装的情况下提供。

Item * Menue:: getItem(int i,Type type)
{
    /*Switch the correct item we want to order*/
    switch (type)
    {
        case special:return _headEdible->getNode(i)->_item;
        break;

        case beverage:return _headBeverage->getNode(i)->_item;
        break;

        case edible:return _headSpecial->getNode(i)->_item;
        break;

        default: return NULL;
        break;
    }
}

这解决了当前的问题,但没有解决潜在的问题:OP对于编写这种复杂程序的程序还不了解他们正在做的事情。该问题的解决方案是阅读更多的教科书,并做一些问题或通过示例工作,以更好地掌握继承和指针。

然后他们应该再次编写Node s的链接列表(Node<T>::getNode,例如,可以轻松地运行到列表的末尾)完全测试它,然后继续编写逻辑取决于链表。试图同时编写两个程序通常会将A部分和B部分中的错误数量相乘,而不是为了调试花费的时间而添加它们。