Sign in to follow this  

Problem With Passing a Class as a type for a template

This topic is 4782 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have written a linked list objects and it works well until u pass in a class as a type when initiating the list. So i have:
class a;  // without body for this example.

linked_list<a> newList;


I get the errors: f:\developement\my documents\program\salamol v201\linked_list.h(25) : error C2512: 'LIST' : no appropriate default constructor available f:\developement\my documents\program\salamol v201\linked_list.h(24) : while compiling class-template member function '__thiscall linked_list<class file>::linked_list<class file>(void)' i do have 1 constructor, which is
	linked_list() : listInitiated(false)
	{
		InitLinkedList();
	}


It seems if i change the creation line to: linked_list<a> newList(); it compiles and links but i cant then use the "newList." syntax on the created list object. Can anyone help with this? ace

Share this post


Link to post
Share on other sites
You'll probably have to show more code, what you have doesn't really give any clues to what the problem is.

Oh and this line:

linked_list<a> newList();
doesn't declare an object; it declares an function called newList that returns a linked_list<a> object. It's one of C++'s more annoying parsing rules.

Share this post


Link to post
Share on other sites
ok so here is the complete source to the whole project im working on.

linked_list.h

#ifndef _S_LINKED_LIST_
#define _S_LINKED_LIST_

#include <stdio.h>
#include <stdlib.h>

template <class TYPE>
class linked_list
{
private:
// MEMBER DATA
struct LIST
{
TYPE _item;

unsigned long nodeNumber;

LIST* next;
LIST* prev;
} start;

public:

linked_list() : listInitiated(false)
{
InitLinkedList();
}

virtual ~linked_list()
{
if (listInitiated == true)
{
KillList();
}
}

// MEMBER DATA
LIST* _node;

// MEMBER METHODS
void _AddNode(TYPE* _inPtr) { if (_inPtr != NULL) AddNode(_inPtr); };
void _RemoveNode() { RemoveNode(); };
void _GotoStart() { GotoStart(); };
void _GotoEnd() { GotoEnd(); };
void _IncNode() { IncNode(); };
void _DecNode() { DecNode(); };
void _KillList() { KillList(); };
void _SwapThisNext() { SwapThisNext(); };
void _SwapThisPrev() { SwapThisPrev(); };

unsigned long _EnumNodes() { return numNodes; };

private:

// MEMBER DATA
bool listInitiated;
unsigned long numNodes;

// MEMBER METHODS
inline void InitLinkedList()
{
start.next = NULL;
_node = &start;
listInitiated = true;
numNodes = 0;
}

inline void AddNode(TYPE* _inPtr)
{
if (listInitiated == true)
{
LIST* lastNode;

// allocate memory for the next list node
_node->next = (struct LIST *) malloc(sizeof(struct LIST));

// increment the number of node counter
numNodes++;

// set a temporary pointer to point to the current node
lastNode = _node;

// move to the next node
_node = _node->next;

// set the prev pointer to the last node
_node->prev = lastNode;

// set the node number
_node->nodeNumber = numNodes;

// copy the info accross
memcpy( &_node->_item, _inPtr, sizeof(_node->_item) );

// set the pointer to the next node to NULL
_node->next = NULL;
}
}

inline void GotoStart()
{
if (listInitiated == true)
{
_node = &start;
_node = _node->next;
}
}

inline void GotoEnd()
{
if (listInitiated == true)
{
/// slow method for getting to teh last node, REDO
_node = &start;
_node = _node->next;

while( _node->next != NULL )
{
_node = _node->next;
}
}
}

inline void IncNode()
{
if (listInitiated == true)
{
if (_node->next != NULL)
{
_node = _node->next;
}
}
}

inline void DecNode()
{
if (listInitiated == true)
{
if (_node->prev != NULL)
{
_node = _node->prev;
}
}
}

inline void KillList()
{
if (listInitiated == true)
{
_node = &start;
_node = _node->next;

if (_node != NULL)
{
while (_node->next != NULL)
{
start.next = _node->next;
free(_node);
_node = start.next;
}
}
free(_node);

listInitiated = false;
}
}

inline void RemoveNode()
{
LIST* currentNext;
LIST* prev;

currentNext = _node->next;
prev = _node->prev;

_node = _node->prev;

free(_node->next);

_node->next = currentNext;

numNodes--;
}

inline void SwapThisNext()
{
_swap(&_node->_item, &_node->next->_item);
}

inline void SwapThisPrev()
{
_swap(&_node->_item, &_node->prev->_item);
}

template <class T>
void _swap(T* inA, T* inB)
{
T temp = NULL;

temp = *inA;
*inA = *inB;
*inB = temp;
}
};

#endif _S_LINKED_LIST_



main.cpp

#include "file.h"
#include "linked_list.h"

int main (void)
{
FILE* fp = fopen("C:\\Documents and Settings\\Dave\\Desktop\\star.bmp", "rb+");

file newFile("C:\\Documents and Settings\\Dave\\Desktop\\star.bmp", "rb+");

return 0;
}



The contents of the file class are irrelevent so i wont bother posting. But thats the 2 files. There is no body file forht elinked_list class cos its a template.

Any help is appreciated, thanx

ace

Share this post


Link to post
Share on other sites
Well, look at your list node struct. It stores an object of the templated type by value, and has no constructor, which means it will use the default constructor for the templated type. If the type that you pass the template doesn't have a default constructor or is an incomplete type, the constructor will fail to compile since the compiler can't apply the default constructor rules.

Share this post


Link to post
Share on other sites
here, ill post the file class.

file.h

#ifndef _FILE_
#define _FILE_

const unsigned int FILE_PATH_SIZE = 400;
const unsigned int FILE_NAME_SIZE = 200;
const unsigned int FILE_EXT_SIZE = 5;
const unsigned int FILE_ACCESS_MODE_SIZE = 5;



#include <stdio.h>
#include <string.h>

class file
{
public:
file();
file(char* filePath, char* accessMode);
virtual ~file();

FILE* GetFilePointer();

private:
void OpenFile();
void CloseFile();

void GetFileNameFromPath();
void GetExtensionFromPath();
void DetermineFileSize();

FILE* fp;

unsigned long fileSize;
char filePath[FILE_PATH_SIZE];
char fileName[FILE_NAME_SIZE];
char fileExt[FILE_EXT_SIZE];
char fileAccessMode[FILE_ACCESS_MODE_SIZE];

bool fileOpen;
};


#endif //_file_



file.cpp

#include "file.h"

//////////////////////////////////////////////////////////////////////////////////////////
// Name: file()
// Params: filePath - pointer to the incoming path
// accessMode - pointer to the incoming access mode
// Desc: Contructor for the file class. Checks the validity of the incoming strings,
// sets the local file data tot eh incoming values and calls the open file func.
//////////////////////////////////////////////////////////////////////////////////////////
file::file(char* filePath, char* accessMode)
{
if ( (filePath != NULL) && (accessMode != NULL) )
{
this->fileOpen = false;
strcpy(&this->filePath[0], filePath);
strcpy(&this->fileAccessMode[0], accessMode);

OpenFile();
}
}

//////////////////////////////////////////////////////////////////////////////////////////
// Name: ~file()
// Params: N/A
// Desc: Destructor for the file class. Calls the CloseFile() function when the
// any objects of this class go out of scope.
//////////////////////////////////////////////////////////////////////////////////////////
file ::~file()
{
CloseFile();
}

//////////////////////////////////////////////////////////////////////////////////////////
// Name: OpenFile()
// Params: N/A
// Desc: After checking whether this file has already been opened, opens if it hasn't
// been opened and sets the value of fileOpen accordingly.
//////////////////////////////////////////////////////////////////////////////////////////
void file::OpenFile()
{
if (fileOpen == false)
{
fp = fopen(&filePath[0], &fileAccessMode[0]);
if (fp != NULL)
{
fileOpen = true;
GetFileNameFromPath();
GetExtensionFromPath();
DetermineFileSize();
}
}
}

//////////////////////////////////////////////////////////////////////////////////////////
// Name: GetFilePointer()
// Params: N/A
// Desc: This function returns pointer returns the member file pointer to the calling
// class only if it is valid, otherwise NULL is returned.
//////////////////////////////////////////////////////////////////////////////////////////
FILE* file::GetFilePointer()
{
if (fileOpen == true)
{
return fp;
}
return NULL;
}

//////////////////////////////////////////////////////////////////////////////////////////
// Name: CloseFile()
// Params: N/A
// Desc: This function closes the file pointed to by the member file pointer only if
// the file has been opened.
//////////////////////////////////////////////////////////////////////////////////////////
void file::CloseFile()
{
if (fileOpen == true)
{
fclose(fp);
if (fp == NULL)
{
fileOpen = true;
}
}
}

//////////////////////////////////////////////////////////////////////////////////////////
// Name: GetFileNameFromPath()
// Params: N/A
// Desc: This function is used to extract the file name
//////////////////////////////////////////////////////////////////////////////////////////
void file::GetFileNameFromPath()
{
unsigned long lengthOfPath = 0;
unsigned long pathPosPtr = 0;

lengthOfPath = strlen(&filePath[0]);

for ( pathPosPtr = (lengthOfPath - 1);
pathPosPtr >= 0;
pathPosPtr--)
{
if ( filePath[pathPosPtr] == '\\')
{
strcat(&fileName[0], &filePath[pathPosPtr+1]);
break;
}
}
}

//////////////////////////////////////////////////////////////////////////////////////////
// Name: GetExtensionFromPath()
// Params: N/A
// Desc: This function is used to extract the file extension
//////////////////////////////////////////////////////////////////////////////////////////
void file::GetExtensionFromPath()
{
unsigned long lengthOfPath = 0;
unsigned long pathPosPtr = 0;

lengthOfPath = strlen(&filePath[0]);

fileExt[0] = NULL;

for ( pathPosPtr = (lengthOfPath - 1);
pathPosPtr >= 0;
pathPosPtr--)
{
if ( filePath[pathPosPtr] == '.')
{
strcat(&fileExt[0], &filePath[pathPosPtr+1]);
break;
}
}
}


//////////////////////////////////////////////////////////////////////////////////////////
// Name: DetermineFileSize()
// Params: N/A
// Desc: This function is used to get the file size of the file.
//////////////////////////////////////////////////////////////////////////////////////////
void file::DetermineFileSize()
{
fseek(fp, 0, SEEK_END);

fileSize = ftell(fp);
}



I added another contructor:

file();

and that seemed to solve the problem.

Is that what i should have done?

ace

Share this post


Link to post
Share on other sites
A better solution would have been to use a pointer to your file objects as the type when creating your list object, since your list class doesn't handle object copying or deletion properly in it's node manipulation routines.

Is there any reason that you aren't using the standard classes for this?

Share this post


Link to post
Share on other sites
Basically because i want to doit mysefl. There is far to much that is done for programmers and i want to become a very good one. So im learning this way.

If STL etc is so easy to use it wont be a problem for me when im done here.

ace

Share this post


Link to post
Share on other sites

This topic is 4782 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this