Inheriting Template Class Constructor Problem

Started by
7 comments, last by Nitage 18 years, 9 months ago
I have a template class that I am trying to inherit from another template class, but the compiler complains 'c:\Documents and Settings\rprice\My Documents\Visual Studio Projects\Terraformer3\nw.h(239): error C2542: 'array' : class object has no constructor for initialization'. The line it fails on is...

template <class T> cachedarray<T>::cachedarray(int in_size, int in_growBy):array(in_size, in_growBy)
{
	// clear pointers
	m_user=NULL;
}

The definition of the original class is...

template <class T> class array
{
protected:
	T* m_array;
	int m_arraySize;
	int m_growBy;
	int m_count;
public:
	array() {m_arraySize=1; m_growBy=1; m_count=0; m_array=new T[m_arraySize];}
	array(int in_size, int in_growBy) {m_arraySize=in_size; m_growBy=in_growBy; m_count=0; m_array=new T[m_arraySize];}
	void Append(T in_element);
	void RemoveAll();
//	void RemoveAll() {m_count=0; return;}
	int GetCount() {return m_count;}

	T& operator[] (int i) {if (i > (m_count-1)) m_count=i+1; return m_array;}
};

The definition of the new class is...

template <class T> class cachedarray : public array
{
protected:
	char m_resourceID[8];	// underlying API resource
	Renderer* m_user;		// and resource user
public:
	cachedarray();
	cachedarray(int in_size, int in_growBy);
	~cachedarray();

	void BindResourceID(Renderer* in_user, void* in_resource);
	void* GetResourceID();
	Renderer* GetResourceUser();

	T& operator[] (int i) {if (i > (m_count-1)) m_count=i+1; return m_array;}
};

Do I have the syntax wrong? I thought I could just pass to the base class constructor even though it's a template. Can I not do this? Thanks!
Advertisement
I believe your problem is that you aren't specifying a T for the class you are inheriting from. That is to say this:

template <class T> class cachedarray : public array
should be:
template <class T> class cachedarray : public array<T>

and so on with all the references to array.
Quote:Original post by SiCrane
I believe your problem is that you aren't specifying a T for the class you are inheriting from. That is to say this:

template <class T> class cachedarray : public array
should be:
template <class T> class cachedarray : public array<T>

and so on with all the references to array.


Thank you. So the class name always need to be qualified with the template class types? Also, it seem my operator definition...

	T& operator[] (int i) {if (i > (m_count-1)) m_count=i+1; return m_array;}


Does not seem to get inherited. Do operator overrides not get inherited by default? If I remove this line from my derived class, I get errors about cannot find operator when I try to reference the array.

Thanks again!
Operators aren't inherited. It's simply not safe. A derived class is not the same type as it's base class; but the operators take the base class type. For example, if operator= were inherited, you could assign a type base to a type derived, but not a derived to derived. It's the sort of feature where the standards committee had to choose between two bad options.
Quote:Original post by Deyja
Operators aren't inherited. It's simply not safe. /snip/


Say what? Operator overloads are inherited. Take a look at std::fstream.

@Raeldor: It seems to work for me once I add the forward declarations necessary to get it to compile. What compiler are you using, and are you sure that you fixed all the necessay references to array?
Quote:Original post by Deyja
Operators aren't inherited. It's simply not safe. A derived class is not the same type as it's base class; but the operators take the base class type. For example, if operator= were inherited, you could assign a type base to a type derived, but not a derived to derived. It's the sort of feature where the standards committee had to choose between two bad options.


Hi friend, maybe this code sample will clear things up for you. cheers

#include <iostream>using namespace std;class one{    public:        one(int num):val(num){}        operator int(){            return val;        }    private:        int val;    };class two : public one{    public:    two(int num):one(num){}        };int main(){    two obj(55);    cout << obj << endl;}


OP:

Why not place the constructor definition in the class declaration? Seems it would simplify things for you, and I bet the problem would go away.
my_life:          nop          jmp my_life
[ Keep track of your TDD cycle using "The Death Star" ] [ Verge Video Editor Support Forums ] [ Principles of Verg-o-nomics ] [ "t00t-orials" ]
Thanks guys. Putting the class type on fixed the problem.

The only remaining issue is having to replicate the operator in the derived class. Is there any concensus as to if operators are inherited? There seems to be some disagreement here.
Operators are inherited like any other function.

The reason there was some confusion may be that its not a very good idea to provide some operators in base classes (especially the assignment operator, which can lead to object slicing if used incorrectly).

No such issue exists with operator[] though and I can't immeadiatley see any problem with the code.

This topic is closed to new replies.

Advertisement