I wrote an abstract class called "List", which I basically use as an interface for other implementation methods of lists (such as dynamic array and linked list).
Now, I have a method called "add", with 2 arguments, the first one is the data to add and the second is the position where to add. I want to set the default value of this position to be the end of the list (i.e, its size).
Here's what I wrote:
#ifndef LIST_H
#define LIST_H
template <class T>
class List
{
public:
List(): m_size(0) {}
virtual bool isEmpty() const=0;
virtual void set(int index, T value)=0;
virtual int getSize() const=0;
virtual void add(T data, int index = m_size )=0; //The problem is here
virtual T remove(int index)=0;
virtual ~List(){}
virtual T operator[](int index) const =0;
virtual bool operator==(const List<T>& other) const =0;
protected:
int m_size;
};
#endif // LIST_H
But I get the following error:
error: invalid use of non-static data member 'List<T>::m_size'|
Is there a way to fix this problem?
Also, is it correct to implement the constructor as I did? do I need to call this constructor in the init line of the derived classes constructors or does the compiler does it implicitly?
Thanks in advance.
CodePudding user response:
You cannot use members as default arguments of methods. Instead write an overload (it doesnt need to be virtual when it calls the virtual add(T,int):
void add(T data) {
add(data,m_size );
}
CodePudding user response:
As you may know, all class instances share the same VTABLE - table of virtual methods. Given that, you can't introduce instance-specific knowledge to that shared source. Just imagine you have two lists of the same type, first one with m_size=10 and another one with m_size=42. How to resolve that conflict? What to do if m_size is changed over time? etc.
So, it's may be worth to introduce two methods, like insert(data, pos) and append(data).
CodePudding user response:
The problem is that you are using m_size as a default parameter for your implementation. As pointed out here, it is not possible to do that straight away. What you could do is overload this function as follows:
virtual void add(T data, int index)=0 // Original - remove the default parameter
void add(T data) // Overload - call with m_size
{
add(data, m_size);
}
This way, all you have to do is override the original function.
