【问题标题】:C++ Template interface (list implementation)C++模板接口(列表实现)
【发布时间】:2015-06-07 10:18:14
【问题描述】:

我正在尝试用 C++ 实现一个列表数据结构。

我想定义一个列表接口,该接口稍后会被 ArrayList 或 LinkedList 等实现继承。

我希望能够像这样使用它

List<int>* testList = new LinkedList<int>;

所以我尝试实现完整的虚拟模板类,但后来意识到我不能混合使用虚拟和模板方法。我尝试了很多不同的方法,并且一直遇到问题。

最好的方法是什么?

编辑(有问题的代码)。我正在尝试使界面看起来像这样:

template<typename T>
class List {
public:
    virtual void add(T*) {};
    virtual void remove(unsigned int) = 0;
    virtual unsigned int size() = 0;
    virtual void get(unsigned int) = 0;

    virtual ~List();
};

然后我尝试在这里实现它:

template<typename T>
class LinkedList : public List<T> {
/* some stuff */
public:
    LinkedList();

    virtual unsigned int size();
    virtual void add(T*); // the problem i guess
    virtual void remove(unsigned int);
    virtual void get(unsigned int);

    virtual ~LinkedList();
 };

【问题讨论】:

  • 你不应该为此需要虚函数模板,整个接口/类的模板就足够了。你能显示给你带来麻烦的代码吗?
  • 请提供部分有问题的源代码。您不能混合使用虚拟方法和模板方法,但您可以在模板类中使用虚拟方法。这应该可以满足您的需求。
  • 请不要。 std::vectorstd::list。不要用 C++ 编写 Java。
  • 您是否阅读过有关 c++ 类及其语法的教程?

标签: c++ class templates interface polymorphism


【解决方案1】:

所以我尝试实现完整的虚拟模板类,但后来 意识到我不能混合使用虚拟和模板ed方法。

您的示例代码表明,您不需要虚拟的模板化方法,而是具有虚拟方法的模板类。前者是不允许的,后者是(这是一个常见的混淆点)。

所以这是完全有效的代码:

#include <iostream>
#include <memory>

template<class T>
class List{
public:
    virtual void push()=0;   
    virtual void pop()=0;
    virtual ~List()=default;
};

template<class T>
class LinkedList: public List<T>{
public:
    virtual void push() {
        std::cout << "Pushed element to Linked List"<< std::endl;
    }
    virtual void pop() {
        std::cout << "Poped element from Linked List"<< std::endl;
    }
};

template<class T>
class ArrayList: public List<T>{
public:
    virtual void push() {
        std::cout << "Pushed element to ArrayList"<< std::endl;
    }
    virtual void pop() {
        std::cout << "Poped element from ArrayList"<< std::endl;
    }
};

int main()
{

    List<int>* list1=new LinkedList<int>();
    List<int>* list2=new ArrayList<int>();
    // And this is how you would actually create objects on the heap nower days:
    std::unique_ptr<List<int>> list3=std::make_unique<LinkedList<int>>();

    list1->push();
    list2->push();
    list3->push();

    list1->pop();
    list2->pop();
    list3->pop();

    delete(list1);
    delete(list2);
    //no delete(list3) needed
    return 0;
}

除此之外,我不知道您为什么要这样做。 C++ 有一个完美的链表实现和数组/向量的实现,并且由于基于迭代器的语义,您可以在它们上运行(几乎)任何算法,而无需公共基类。

我很抱歉,如果这听起来很苛刻,但看起来你是从 Java 来的,并试图学习 C++。但不是学习 C++,而是尝试编写包装器,使 C++ 看起来像 java。虽然这在大多数情况下肯定是可能的(只要您不要忘记,标准 c++ 没有垃圾收集器),但它通常不是一种明智的方法。当然,这是否适用于您的情况取决于您的应用程序。但我的建议是了解迭代器和标准库算法。

【讨论】:

    猜你喜欢
    • 2013-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    相关资源
    最近更新 更多