Template class copy constructor

M

muzmail

I have declared a copy constructor for a template class in a Visual C++
project but for some reason the compiler ignores it. I can put syntax
errors in the copy constructor and the compiler ignores them.

So what's the problem with my code?



#ifndef threedeematrix_h
#define threedeematrix_h

#include <vector>

using namespace std;
typedef unsigned char BYTE;

template <class pixel_data>
class C3DVector
{
public:

inline C3DVector():m_dimRow(0), m_dimCol(0), m_dimZed(0){;}
inline C3DVector(int nRow, int nCol, int
nZed):m_dimRow(nRow),m_dimCol(nCol),m_dimZed(nZed)
{
m_3DVector = new pixel_data[nRow*nCol*nZed];
}
explicit inline C3DVector(const C3DVector<pixel_data>& rhs)
{
// we're assuming they're the same size
if (this != &rhs)
{
delete[] m_3DVector;
rhs.getdimensions(m_dimRow, m_dimCol);
m_dimZed = 3;
m_3DVector = new pixel_data[m_dimRow*m_dimCol*m_dimZed];
for (unsigned int x=0; x<m_dimRow; x++)
for (unsigned int y=0; y<m_dimCol; y++)
for (unsigned int z=0; z<m_dimZed; z++)
m_3DVector[x*m_dimCol*m_dimZed+y*m_dimZed+z]=rhs(x,y,z); //
replaced indirection with direct access!
}
}
inline ~C3DVector()
{
delete[] m_3DVector;
}

inline C3DVector<pixel_data>& operator= (C3DVector<pixel_data>&
second)
{
// we're assuming they're the same size
if (this != &second)
for (unsigned int x=0; x<m_dimRow; x++)
for (unsigned int y=0; y<m_dimCol; y++)
for (unsigned int z=0; z<m_dimZed; z++)
m_3DVector[x*m_dimCol*m_dimZed+y*m_dimZed+z]=second(x,y,z); //
replaced
return(*this);
}
inline pixel_data& operator()(int x, int y, int z)
{
if (x<0 || x>m_dimRow ||
y<0 || y>m_dimCol ||
z<0 || z>m_dimZed)
throw("Access 3D vector out of bounds");
return(m_3DVector[x*m_dimCol*m_dimZed+y*m_dimZed+z]);
}

void writegreybmp(int colourcomponent,
CString outputfilename,
BITMAPFILEHEADER bfh,
BITMAPINFOHEADER bih,
bool popupbox);

void writecolourbmp(CString outputfilename,
BITMAPFILEHEADER bfh,
BITMAPINFOHEADER bih,
bool popupbox);

bool capturecolourbmp(CString m_csInputFilename);
inline void getdimensions(unsigned int row, unsigned int col)
{
row = m_dimRow;
col = m_dimCol;
}
protected:
pixel_data* m_3DVector;

unsigned int m_dimRow;
unsigned int m_dimCol;
unsigned int m_dimZed;
static const int RED=0, GREEN=1, BLUE=2;
};

#endif


Thanks in advance
-Muz
 
A

amparikh

I have declared a copy constructor for a template class in a Visual C++
project but for some reason the compiler ignores it. I can put syntax
errors in the copy constructor and the compiler ignores them.

So what's the problem with my code?



#ifndef threedeematrix_h
#define threedeematrix_h

#include <vector>

using namespace std;
typedef unsigned char BYTE;

template <class pixel_data>
class C3DVector
{
public:

inline C3DVector():m_dimRow(0), m_dimCol(0), m_dimZed(0){;}
inline C3DVector(int nRow, int nCol, int
nZed):m_dimRow(nRow),m_dimCol(nCol),m_dimZed(nZed)
{
m_3DVector = new pixel_data[nRow*nCol*nZed];
}
explicit inline C3DVector(const C3DVector<pixel_data>& rhs)
{
// we're assuming they're the same size
if (this != &rhs)
{
delete[] m_3DVector;
rhs.getdimensions(m_dimRow, m_dimCol);
m_dimZed = 3;
m_3DVector = new pixel_data[m_dimRow*m_dimCol*m_dimZed];
for (unsigned int x=0; x<m_dimRow; x++)
for (unsigned int y=0; y<m_dimCol; y++)
for (unsigned int z=0; z<m_dimZed; z++)
m_3DVector[x*m_dimCol*m_dimZed+y*m_dimZed+z]=rhs(x,y,z); //
replaced indirection with direct access!
}
}
inline ~C3DVector()
{
delete[] m_3DVector;
}

inline C3DVector<pixel_data>& operator= (C3DVector<pixel_data>&
second)
{
// we're assuming they're the same size
if (this != &second)
for (unsigned int x=0; x<m_dimRow; x++)
for (unsigned int y=0; y<m_dimCol; y++)
for (unsigned int z=0; z<m_dimZed; z++)
m_3DVector[x*m_dimCol*m_dimZed+y*m_dimZed+z]=second(x,y,z); //
replaced
return(*this);
}
inline pixel_data& operator()(int x, int y, int z)
{
if (x<0 || x>m_dimRow ||
y<0 || y>m_dimCol ||
z<0 || z>m_dimZed)
throw("Access 3D vector out of bounds");
return(m_3DVector[x*m_dimCol*m_dimZed+y*m_dimZed+z]);
}

void writegreybmp(int colourcomponent,
CString outputfilename,
BITMAPFILEHEADER bfh,
BITMAPINFOHEADER bih,
bool popupbox);

void writecolourbmp(CString outputfilename,
BITMAPFILEHEADER bfh,
BITMAPINFOHEADER bih,
bool popupbox);

bool capturecolourbmp(CString m_csInputFilename);
inline void getdimensions(unsigned int row, unsigned int col)
{
row = m_dimRow;
col = m_dimCol;
}
protected:
pixel_data* m_3DVector;

unsigned int m_dimRow;
unsigned int m_dimCol;
unsigned int m_dimZed;
static const int RED=0, GREEN=1, BLUE=2;
};

#endif


Thanks in advance
-Muz

Are you sure you are calling it correctly ? Copy constructor looks ok
as far as the signature is concerned.

Also, you are calling too non-const functions(getdimensions and
operator()) on the const rhs object in the copy constructor. That will
give you compiler errors. Make them constant and the code should
compile and the copy constructor should get called.
 
A

amparikh

I have declared a copy constructor for a template class in a Visual C++
project but for some reason the compiler ignores it. I can put syntax
errors in the copy constructor and the compiler ignores them.

So what's the problem with my code?



#ifndef threedeematrix_h
#define threedeematrix_h

#include <vector>

using namespace std;
typedef unsigned char BYTE;

template <class pixel_data>
class C3DVector
{
public:

inline C3DVector():m_dimRow(0), m_dimCol(0), m_dimZed(0){;}
inline C3DVector(int nRow, int nCol, int
nZed):m_dimRow(nRow),m_dimCol(nCol),m_dimZed(nZed)
{
m_3DVector = new pixel_data[nRow*nCol*nZed];
}
explicit inline C3DVector(const C3DVector<pixel_data>& rhs)
{
// we're assuming they're the same size
if (this != &rhs)
{
delete[] m_3DVector;
rhs.getdimensions(m_dimRow, m_dimCol);
m_dimZed = 3;
m_3DVector = new pixel_data[m_dimRow*m_dimCol*m_dimZed];
for (unsigned int x=0; x<m_dimRow; x++)
for (unsigned int y=0; y<m_dimCol; y++)
for (unsigned int z=0; z<m_dimZed; z++)
m_3DVector[x*m_dimCol*m_dimZed+y*m_dimZed+z]=rhs(x,y,z); //
replaced indirection with direct access!
}
}
inline ~C3DVector()
{
delete[] m_3DVector;
}

inline C3DVector<pixel_data>& operator= (C3DVector<pixel_data>&
second)
{
// we're assuming they're the same size
if (this != &second)
for (unsigned int x=0; x<m_dimRow; x++)
for (unsigned int y=0; y<m_dimCol; y++)
for (unsigned int z=0; z<m_dimZed; z++)
m_3DVector[x*m_dimCol*m_dimZed+y*m_dimZed+z]=second(x,y,z); //
replaced
return(*this);
}
inline pixel_data& operator()(int x, int y, int z)
{
if (x<0 || x>m_dimRow ||
y<0 || y>m_dimCol ||
z<0 || z>m_dimZed)
throw("Access 3D vector out of bounds");
return(m_3DVector[x*m_dimCol*m_dimZed+y*m_dimZed+z]);
}

void writegreybmp(int colourcomponent,
CString outputfilename,
BITMAPFILEHEADER bfh,
BITMAPINFOHEADER bih,
bool popupbox);

void writecolourbmp(CString outputfilename,
BITMAPFILEHEADER bfh,
BITMAPINFOHEADER bih,
bool popupbox);

bool capturecolourbmp(CString m_csInputFilename);
inline void getdimensions(unsigned int row, unsigned int col)
{
row = m_dimRow;
col = m_dimCol;
}
protected:
pixel_data* m_3DVector;

unsigned int m_dimRow;
unsigned int m_dimCol;
unsigned int m_dimZed;
static const int RED=0, GREEN=1, BLUE=2;
};

#endif


Thanks in advance
-Muz

Are you sure you are calling it correctly ? Copy constructor looks ok
as far as the signature is concerned.

Also, you are calling too non-const functions(getdimensions and
operator()) on the const rhs object in the copy constructor. That will
give you compiler errors. Make them constant and the code should
compile and the copy constructor should get called.
 
M

muzmail

In the program an object of the C3DVector class is added to an stl
deque so i think the copy constructor should be called to put a copy in
the deque.

The program crashes around this point and Visual c++'s call stack shows
that a C3DVector copy constructor is called but it isn't the one I
wrote. Visual c++ says "there is no source code available for that
location" when I click on it, I think that means it's generating its
own.
SD2.exe!C3DVector<unsigned char>::C3DVector<unsigned char>(const C3DVector<unsigned char> & __that={...}) + 0x2f C++
I have made some template specialization functions for unsigned char
but not a copy constructor for unsigned char.

Also, I should be clear on this. The program and the C3DVector class
compile even when I take out all the code in the copy constructor and
put gibberish in there. That doesn't happen with the other functions.
 
A

amparikh

In the program an object of the C3DVector class is added to an stl
deque so i think the copy constructor should be called to put a copy in
the deque.

The program crashes around this point and Visual c++'s call stack shows
that a C3DVector copy constructor is called but it isn't the one I
wrote. Visual c++ says "there is no source code available for that
location" when I click on it, I think that means it's generating its
own.
I have made some template specialization functions for unsigned char
but not a copy constructor for unsigned char.

I think I have seen issues debugging templates(and even some cirtual
functions) with VC++ debugger where you cannot trace in into those
functions at times if you dont have all the debugging options set.
Probably that is why it says there is no source code and then you have
to go past. Are you sure you have all the debugging options set
correctly ? Both in the C/C++ options and Linker options.

Also post the entire code, because the code you posted didnt show any
specialization. If you cant post your real code, try making a test code
and post it here to demonstrate the problem.
Also, I should be clear on this. The program and the C3DVector class
compile even when I take out all the code in the copy constructor and
put gibberish in there. That doesn't happen with the other functions.

Again if you are using specialization, post all the code here. Based on
what you are describing, you dont have a copy constructor in the
specialized code( and the compiler might be generating that for you ??)
 
M

muzmail

Alright, here's a condensed version of the C3DVector class which may
allow you to help.

#ifndef threedeematrix_h
#define threedeematrix_h

#include <vector>

using namespace std;typedef unsigned char BYTE;

template <class pixel_data>
class C3DVector
{public:
inline C3DVector():m_dimRow(0), m_dimCol(0), m_dimZed(0){;}
inline C3DVector(int nRow, int nCol, int
nZed):m_dimRow(nRow),m_dimCol(nCol),m_dimZed(nZed)
{m_3DVector = new pixel_data[nRow*nCol*nZed];}


template<class pixel_data> C3DVector(const C3DVector<pixel_data>& rhs)
{
// code never reaches this point
}


//other functions
protected:
pixel_data* m_3DVector; unsigned int m_dimRow; unsigned int
m_dimCol; unsigned int m_dimZed; static const int RED=0, GREEN=1,
BLUE=2;
};
#endif


And here's the throughly unremarkable template specialization header
file (the problem better not be here).


#ifndef threedeeBYTEmatrix_h
#define threedeeBYTEmatrix_h
#include <vector>
template<>
void C3DVector<BYTE>::
writegreybmp(int colourcomponent,
CString outputfilename,
BITMAPFILEHEADER bfh,
BITMAPINFOHEADER bih,
bool popupbox);
template<>
void C3DVector<BYTE>::
writecolourbmp(CString outputfilename,
BITMAPFILEHEADER bfh,
BITMAPINFOHEADER bih,
bool popupbox);
template<>
bool C3DVector<BYTE>::
capturecolourbmp(CString m_csInputFilename);
#endif
 
A

amparikh

Alright, here's a condensed version of the C3DVector class which may
allow you to help.

#ifndef threedeematrix_h
#define threedeematrix_h

#include <vector>

using namespace std;typedef unsigned char BYTE;

template <class pixel_data>
class C3DVector
{public:
inline C3DVector():m_dimRow(0), m_dimCol(0), m_dimZed(0){;}
inline C3DVector(int nRow, int nCol, int
nZed):m_dimRow(nRow),m_dimCol(nCol),m_dimZed(nZed)
{m_3DVector = new pixel_data[nRow*nCol*nZed];}


template<class pixel_data> C3DVector(const C3DVector<pixel_data>& rhs)
{
// code never reaches this point
}


//other functions
protected:
pixel_data* m_3DVector; unsigned int m_dimRow; unsigned int
m_dimCol; unsigned int m_dimZed; static const int RED=0, GREEN=1,
BLUE=2;
};
#endif


And here's the throughly unremarkable template specialization header
file (the problem better not be here).


#ifndef threedeeBYTEmatrix_h
#define threedeeBYTEmatrix_h
#include <vector>
template<>
void C3DVector<BYTE>::
writegreybmp(int colourcomponent,
CString outputfilename,
BITMAPFILEHEADER bfh,
BITMAPINFOHEADER bih,
bool popupbox);
template<>
void C3DVector<BYTE>::
writecolourbmp(CString outputfilename,
BITMAPFILEHEADER bfh,
BITMAPINFOHEADER bih,
bool popupbox);
template<>
bool C3DVector<BYTE>::
capturecolourbmp(CString m_csInputFilename);
#endif

The code that I see here is that you have specialized the member
functions ? I am not sure if this code will even compile.
First you need to specialize your class C3DVector for BYTE( maybe you
havent posted that code ) and then implement those member functions for
that specialized class. Going by your declarations and defintions of
member functions, they dont seemed to be member templates.

Show how you are specializing the C3DVector class. Does it have a copy
constructor ? Because if you are 'explicity" instantiating the
specialized C3DVector, the copy constructor in the non-spec C3DVector
has nothing to do with it and that is why it is not getting called.
It is not inheritance, if at all that is what you are thinking.
 
R

red floyd

I have declared a copy constructor for a template class in a Visual C++
project but for some reason the compiler ignores it. I can put syntax
errors in the copy constructor and the compiler ignores them.

So what's the problem with my code?



#ifndef threedeematrix_h
#define threedeematrix_h

#include <vector>

using namespace std;
typedef unsigned char BYTE;

template <class pixel_data>
class C3DVector
{
public:

inline C3DVector():m_dimRow(0), m_dimCol(0), m_dimZed(0){;}
inline C3DVector(int nRow, int nCol, int
nZed):m_dimRow(nRow),m_dimCol(nCol),m_dimZed(nZed)
{
m_3DVector = new pixel_data[nRow*nCol*nZed];
}
explicit inline C3DVector(const C3DVector<pixel_data>& rhs)
{
// we're assuming they're the same size
if (this != &rhs)
{
delete[] m_3DVector;
rhs.getdimensions(m_dimRow, m_dimCol);
m_dimZed = 3;
m_3DVector = new pixel_data[m_dimRow*m_dimCol*m_dimZed];
for (unsigned int x=0; x<m_dimRow; x++)
for (unsigned int y=0; y<m_dimCol; y++)
for (unsigned int z=0; z<m_dimZed; z++)
m_3DVector[x*m_dimCol*m_dimZed+y*m_dimZed+z]=rhs(x,y,z); //
replaced indirection with direct access!
}
}

Is there a reason your copy constructor is explicit?

Also, what version of VC are you using? VC6 (and VC7 aka 2002) is
notorious for poor template support. VC7.1 aka 2003 is fairly Standard
compliant.
 
A

Alexander Grigoriev

Besides from other things, your copy constructor declaration/definition is
incorrect.
You should write simply:

C3DVector(const C3DVector & rhs)
{
// do your copy here
}
 
M

muzmail

So, I left work on Friday, vowing to make a post about the resolution
to my problem on Monday. On Monday I busy doing other stuff so I
finally got a chance to respond on Tuesday, and I can't remember how
the problem was solved.
The program compiles now and calls the copy constructor when necessary
so I can post an abridged copy of the code but I can't say exactly how
I fixed it.

I'd just like to thank everybody for their suggestions and help in C++
code. I really appreciate it.

-Muz

#ifndef threedeematrix_h
#define threedeematrix_h

using namespace std;
typedef unsigned char BYTE;

template <class pixel_data>
class C3DVector
{
public:

inline C3DVector():m_dimRow(0), m_dimCol(0), m_dimZed(0),
m_3DVector(NULL){}
inline C3DVector(int nRow, int nCol, int
nZed):m_dimRow(nRow),m_dimCol(nCol),m_dimZed(nZed), m_3DVector(new
pixel_data[nRow*nCol*nZed])
{}

inline C3DVector(const C3DVector<pixel_data>& source)
{
copyelements(source);
}

~C3DVector();
C3DVector<pixel_data>& operator= (C3DVector<pixel_data>& source);
void copyelements(const C3DVector<pixel_data>& source);
pixel_data& operator() (int x, int y, int z) const;
void getdimensions (unsigned int& row, unsigned int& col, unsigned
int& zed)const;

// the following functions are only defined for C3DVector<BYTE>
void writegreybmp(int colourcomponent, CString outputfilename,
BITMAPFILEHEADER bfh, BITMAPINFOHEADER bih, bool popupbox);
void writecolourbmp(CString outputfilename, BITMAPFILEHEADER bfh,
BITMAPINFOHEADER bih, bool popupbox);
bool capturecolourbmp(CString m_csInputFilename);

protected:
unsigned int m_dimRow;
unsigned int m_dimCol;
unsigned int m_dimZed;
pixel_data* m_3DVector;
static const int RED=0, GREEN=1, BLUE=2;
};
#endif
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top