// my main
#include <iostream>
#include "LinkedList.txx"
class A
{
public:
virtualvoid print(std::ostream& os) const =0;
};
std::ostream& operator << (std::ostream& os, const A* a)
{
a->print(os);
return os;
}
class B : public A
{
virtualvoid print(std::ostream& os) const
{
os << "B print";
}
};
class C : public A
{
virtualvoid print(std::ostream& os) const
{
os << "C print";
}
};
int main()
{
B b1,b2;
C c1,c2;
// std::cout << ((A*)(&c1));
LinkedList<A*> list;
list.insert(&b1);
list.insert(&c1);
list.insert(&c2);
list.insert(&b2);
std::cout << list << std::endl;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
//file ListNode.txx
#ifndef _LISTNODE_H
#define _LISTNODE_H
template <class T>
class ListNode
{
public:
T *_data;
ListNode *_next; // “ ListNode<T> *_next “ is also correct
ListNode(T *data, ListNode* next)
: _data(data), _next(next) {}
};
#endif
g++ app.cpp -o app
app.cpp: In function ‘int main()’:
app.cpp:37: error: no matching function for call to ‘LinkedList<A*>::insert(B*)’
LinkedList.txx:50: note: candidates are: void LinkedList<T>::insert(T&) [with T = A*]
app.cpp:38: error: no matching function for call to ‘LinkedList<A*>::insert(C*)’
LinkedList.txx:50: note: candidates are: void LinkedList<T>::insert(T&) [with T = A*]
app.cpp:39: error: no matching function for call to ‘LinkedList<A*>::insert(C*)’
LinkedList.txx:50: note: candidates are: void LinkedList<T>::insert(T&) [with T = A*]
app.cpp:40: error: no matching function for call to ‘LinkedList<A*>::insert(B*)’
LinkedList.txx:50: note: candidates are: void LinkedList<T>::insert(T&) [with T = A*]
I think it is due to the fact that the insert function is expecting a reference.
So if T is A* then the function is expecting A*& (reference to a pointer to class A).
The compiler will inplicitly convert a derived class pointer) to a base class pointer
but it wont convert a derived class pointer to a reference to a base class pointer.
base class*& = derived class* ; //Error
So try this instead: void insert(T data); //no longer a reference
1 2 3 4 5
template <class T>
void LinkedList<T>::insert(T data)
{
_head = new ListNode<T>(&data,_head); //EDIT - see comment below.
}
EDIT:
Although now I think about it - you may have to make a specialization for when T is a pointer.
and received the address of the same objects so the 'default' Copy constructor will not be called. and there is nothing wrong with that. thats because of the receiving function is void LinkedList<T>::insert(T& data) .
in other worlds I send:
1 2 3
an object of type B which inherit from the interface A and the received func is
void LinkedList<A*>::insert(A*& data) //my data type is A* because A is interface and I can't allocate it
but the compiler still showing that errors above !!
ne555, the problem is when I make the change like this:
1 2 3
void LinkedList<T>::insert( const T &data ){
head = new ListNode<T>(data, head);
}
and from main I do :
1 2 3
B b1,b2;
LinkedList<A*> list;
list.insert(b1);
whe compiler will show:
1 2 3
app.cpp: In function ‘int main()’:
app.cpp:37: error: no matching function for call to ‘LinkedList<A*>::insert(B&)’
LinkedList.txx:52: note: candidates are: void LinkedList<T>::insert(const T&) [with T = A*]
so what I'm suggesting is to send : list.insert(&b1); // not list.insert(b1) !!
and the inset woult look like that:
1 2 3 4 5
void LinkedList<T>::insert(T data) // <T> is A* and without const
{
_head = new ListNode<T>(&data,_head);
}
//file LinkedList.txx
#ifndef _LINKEDLIST_H
#define _LINKEDLIST_H
#include <iostream>
#include "ListNode.txx"
usingnamespace std;
template <class T>
class LinkedList;
template <class T> // *template function*
ostream& operator <<(ostream& os, const LinkedList<T>& list);
template <class T>
class LinkedList
{
private:
ListNode<T>* _head; // the '<T>' is needed here
bool first;
public:
LinkedList() : _head(NULL),first(true) {}
void insert(const T &data);
//void print (ostream&) const;
friend ostream& operator << <>(ostream& os, const LinkedList<T>& list);
};
template <class T> // *template function*
ostream& operator <<(ostream& os, const LinkedList<T>& list)
{
ListNode<T> *tmp = list._head;
while(tmp != NULL)
{
os << " -> ";
os<<(*(tmp->_data));
tmp = tmp->_next;
}
return os;
}
template <class T>
void LinkedList<T>::insert(const T &data) // const, make sure I'm not changing data
{
_head = new ListNode<T>(data,_head); // sending data which is A*
}
#endif
the main() is the same as above
my question is:
1. when I send _head = new ListNode<T>(data,_head); // sending data which is A* , and the received function is: ListNode(const T &data, ListNode* next) {...}. there is no copy was made from object data right? and if the received function was ListNode(T data, ListNode* next) {...}. is there any copy that was made??
once I have answers I'll ask another intrinsic question !!
thanks