C++模板接口(列表实现)
C++ Template interface (list implementation)
我正在尝试用 C++ 实现列表数据结构。
我想定义一个列表接口,稍后将由 ArrayList 或 LinkedList 等实现继承。
我希望能够像
一样使用它
List<int>* testList = new LinkedList<int>;
所以我尝试实现完整的虚拟模板化 class 但后来意识到我不能混合虚拟和模板化方法。我尝试了很多不同的方法,但一路上都遇到了问题。
最好的方法是什么?
编辑(有问题的代码)。我试图让界面看起来像这样:
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();
};
So i've tried to implement full virtual templated class but then
realized i cannot mix virtual and templated methods.
您的示例代码表明,您不需要虚拟的模板化方法,而是需要具有虚拟方法的模板 class。前者是不允许的,后者是(这是一个常见的混淆点)。
所以这是完全有效的代码:
#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++ 有链表的完美实现和 and array/vector 的实现,并且由于基于迭代器的语义,您可以 运行 (几乎)任何算法,而不需要公共基础 class.
抱歉,如果这听起来很刺耳,但看起来您来自 Java 并且正在尝试学习 C++。但是你没有学习 C++,而是尝试编写包装器,这使 C++ 看起来像 java。虽然这在大多数情况下肯定是可行的(只要您不要忘记,标准 C++ 没有垃圾收集器),但它通常不是一个明智的方法。当然,这是否适用于您的情况取决于您的申请。但我的建议是了解迭代器和标准库算法。
我正在尝试用 C++ 实现列表数据结构。
我想定义一个列表接口,稍后将由 ArrayList 或 LinkedList 等实现继承。
我希望能够像
一样使用它List<int>* testList = new LinkedList<int>;
所以我尝试实现完整的虚拟模板化 class 但后来意识到我不能混合虚拟和模板化方法。我尝试了很多不同的方法,但一路上都遇到了问题。
最好的方法是什么?
编辑(有问题的代码)。我试图让界面看起来像这样:
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();
};
So i've tried to implement full virtual templated class but then realized i cannot mix virtual and templated methods.
您的示例代码表明,您不需要虚拟的模板化方法,而是需要具有虚拟方法的模板 class。前者是不允许的,后者是(这是一个常见的混淆点)。
所以这是完全有效的代码:
#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++ 有链表的完美实现和 and array/vector 的实现,并且由于基于迭代器的语义,您可以 运行 (几乎)任何算法,而不需要公共基础 class.
抱歉,如果这听起来很刺耳,但看起来您来自 Java 并且正在尝试学习 C++。但是你没有学习 C++,而是尝试编写包装器,这使 C++ 看起来像 java。虽然这在大多数情况下肯定是可行的(只要您不要忘记,标准 C++ 没有垃圾收集器),但它通常不是一个明智的方法。当然,这是否适用于您的情况取决于您的申请。但我的建议是了解迭代器和标准库算法。