Я сделал шаблон класса под названием Очередь но у меня возникают проблемы при попытке создать экземпляр с указателем на другой класс с именем Worker в качестве типа. Queue<Worker*>
Я думаю, что проблема заключается в следующем методе:
// Add item to queue
template <typename Type>
bool Queue<Type>::enqueue(const Type& item)
{
if (isfull())
return false;
Node* add = new Node; // create node
// on failure, new throws std::bad_alloc exception
add->item = item; // set node pointers (shallow copying!!!!!)
add->next = nullptr;
items++;
if (front == nullptr) // if queue is empty,
front = add; // place item at front
else
rear->next = add; // else place at rear
rear = add; // have rear point to new node
return true;
}
В случае, когда параметр типа является указателем, мне нужно скопировать указанное значение, а не адрес (я использую динамическое управление памятью), чтобы избежать сбоя программы.
Я не знаю, как решить это с помощью шаблона.
Любая помощь?
Хотя это приведет к небольшому дублированию кода, вы можете создать специализацию своего Queue
класс для создания экземпляров с указателями. Моя рекомендация, чтобы уменьшить количество дублирования кода, состоит в том, чтобы создать базовый класс, который будет наследовать каждый специализированный класс, где базовый класс содержит все методы и члены, которые не изменятся в зависимости от типа, которым этот класс является. создан с.
Так, например:
template<typename T>
base_queue; //keep everything "common" in this class
template<typename T>
queue : public base_queue<T> { ... }; //unspecialized queue class
template<typename T>
queue<T*> : public base_queue<T> { ... }; //pointer specialized version
Теперь в специализированной версии вашего Queue<T*>
класс, твой enqueue
Метод может выглядеть следующим образом:
template <typename T>
bool Queue<T*>::enqueue(const T* item)
{
//... code
add->item = *item; // copy the value being pointed to, not the pointer itself
//... more code
return true;
}
Используйте черты техники.
Я имею в виду определение простой структуры, в которой будет реализована вся магия. Примерно так: deep_copy:
template <typename T>
struct deep_copy {
void do_copy(T& d, const T& s)
{
d = s;
}
};
И специализация для указателей
template <typename T>
struct deep_copy<T*> {
void do_copy(T*& d, const T* s)
{
if(s) d=new(*s); else d=0; }};
}
};
[UPDATE1] Подробнее и больше примеров:
И используйте deep_copy в своей очереди:
template <typename T>
class Queue {
public:
void push_back(const T& elem)
{
Node* n = new Node();
copyTraits.doCopy(n->elem, elem);
}
private:
deep_copy<T> copyTraits;
};
Или даже лучше сделать его параметром по умолчанию для вашего шаблона, как меньше<> по умолчанию для карты.
template <typename T, typename CopyTraits = deep_copy<T> >
class Queue {
public:
void push_back(const T& elem)
{
Node* n = new Node();
copyTraits.doCopy(n->elem, elem);
}
private:
CopyTraits copyTraits;
};
И не забудьте про метод уничтожения, если хотите Queue::~Qeueu()
д-тор на всякий случай:
template <typename T>
struct deep_copy {
void do_copy(T& d, const T& s)
{
d = s;
}
void do_destroy(const T& elem) {} // do nothing
};template <typename T>
struct deep_copy<T*> {
void do_copy(T*& d, const T* s)
{
if(s) d=new(*s); else d=0; }};
}
void do_destroy(const T& elem) {
delete elem;
}
};template <typename T, typename AllocTraits = deep_copy<T> >
class Queue {
public:
...
~Queue() {
for (n in Nodes) { // pseudo-code
allocTraits.doDestroy(n->elem);
}
}
private:
AllocTraits allocTraits;
};