Template class copy constructor

Discussion in 'C++' started by muzmail@gmail.com, Mar 10, 2006.

  1. Guest

    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
    , Mar 10, 2006
    #1
    1. Advertising

  2. Guest

    wrote:
    > 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.
    , Mar 10, 2006
    #2
    1. Advertising

  3. Guest

    wrote:
    > 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.
    , Mar 10, 2006
    #3
  4. Guest

    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.
    , Mar 10, 2006
    #4
  5. Guest

    wrote:
    > 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.


    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 ??)
    , Mar 10, 2006
    #5
  6. Guest

    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
    , Mar 10, 2006
    #6
  7. Guest

    wrote:
    > 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.
    , Mar 10, 2006
    #7
  8. red floyd Guest

    wrote:
    > 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.
    red floyd, Mar 10, 2006
    #8
  9. Besides from other things, your copy constructor declaration/definition is
    incorrect.
    You should write simply:

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

    <> wrote in message
    news:...
    > 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
    >
    Alexander Grigoriev, Mar 11, 2006
    #9
  10. Guest

    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
    , Mar 14, 2006
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. christopher diggins
    Replies:
    16
    Views:
    730
    Pete Becker
    May 4, 2005
  2. ali
    Replies:
    4
    Views:
    558
    David Harmon
    Mar 5, 2007
  3. Donovan Parks

    Copy Constructor with Template Class

    Donovan Parks, Sep 29, 2007, in forum: C++
    Replies:
    2
    Views:
    3,020
    James Kanze
    Oct 1, 2007
  4. Generic Usenet Account
    Replies:
    10
    Views:
    2,197
  5. cinsk
    Replies:
    35
    Views:
    2,556
    James Kanze
    Oct 11, 2010
Loading...

Share This Page