Writing a simple copy constructor
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14

Thread: Writing a simple copy constructor

  1. #1
    Join Date
    Dec 2010
    Posts
    646

    Writing a simple copy constructor

    Code:
    class Matrix4
    {
        Matrix4(float mat[4][4])
        {
              memcpy (m, mat, 16);
        }
        float m[4][4];
    };
    
    float m[4][4];
    cam->getProj(m);
    
    Matrix4 matProj(m);
    The above snippet doesn't compile, please correct my mistakes in syntax.
    Thanks
    Jack

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,544

    Re: Writing a simple copy constructor

    Neither cam nor getProj() is declsred.
    Other errors you could get from your compiler!
    Victor Nijegorodov

  3. #3
    Join Date
    Apr 1999
    Posts
    27,444

    Re: Writing a simple copy constructor

    Code:
    class Matrix4
    {
        Matrix4(float mat[4][4])
    This is not a copy constructor. A copy constructor takes a Matrix4 as a parameter (reference, const reference).

    Second, that parameter, regardless of how many dimensions you stick inside of the [][], all degrades to a pointer. There is no guarantee that what is passed is actually has 4 rows of floats.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; December 10th, 2012 at 04:54 AM.

  4. #4
    Join Date
    Dec 2010
    Posts
    646

    Re: Writing a simple copy constructor

    Hello Victor,
    Code:
    class Matrix4
    {
    public:
    	Matrix4()
    	{
    	}
    
    	Matrix4(float mat[4][4]) 
    	{
    		memcpy (m, mat, 16);
    	}
    	
    private:
    	float m[4][4];
    };
    
    Matrix4 maxViewMatrix = CalculateViewMatrix(e, t, Point3(0, 0, 1));
    
    d3dViewXform = Convert_2_D3D_Matrix(maxViewMatrix);
    
    D3DXMATRIX Convert_2_D3D_Matrix(Matrix4 mat)
    {
    	D3DXMATRIX m;
    	return m;
    }
    Error error C2664: the 'Convert_2_D3D_Matrix': unable to parameter 1 from 'Matrix4' convert 'float [] [4]' d: \ users \ documents \ visual studio 2010 \ projects \ simexporter \ simexporter \ simexporter.cpp 367SimExporter
    Last edited by lucky6969b; December 10th, 2012 at 04:58 AM.

  5. #5
    Join Date
    Dec 2010
    Posts
    646

    Re: Writing a simple copy constructor

    Hello Paul,
    How should I take in a float[4][4] parameter and convert it to a Matrix4?
    Thanks
    Jack

  6. #6
    Join Date
    Apr 1999
    Posts
    27,444

    Re: Writing a simple copy constructor

    Quote Originally Posted by lucky6969b View Post
    Hello Paul,
    How should I take in a float[4][4] parameter and convert it to a Matrix4?
    Please post a real, compilable example. The following compiles without errors using the Comeau C++ online compiler:
    Code:
    #include <cstring>
    class Matrix4
    {
        public:
        Matrix4(float mat[4][4])
        {
           memcpy (m, mat, 16);
        }
        float m[4][4];
    };
    
    int main()
    {
        float m[4][4];
        Matrix4 matProj(m);
    }
    Whenever you get a compiler error, it is imperative that you post a valid example. Your example contained numerous errors, and who knows if one error triggers other errors that are unrelated. For example, your constructor is not public, so how can you call it from any function? I made it public, added the appropriate headers, a main() program, and everything compiles successfully.

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Dec 2010
    Posts
    646

    Re: Writing a simple copy constructor

    All problems fixed. Thanks a lot

  8. #8
    Join Date
    Apr 1999
    Posts
    27,444

    Re: Writing a simple copy constructor

    Quote Originally Posted by lucky6969b View Post
    Hello Victor,
    Code:
    D3DXMATRIX Convert_2_D3D_Matrix(Matrix4 mat)
    {
    	D3DXMATRIX m;
    	return m;
    }
    Why are you passing mat by value? That line does call the copy constructor. You should be passing this by const reference.

    Anyway, there is still no error with this example:
    Code:
    #include <cstring>
    
    class Matrix4
    {
        public:
    
        Matrix4(float mat[4][4])
        { memcpy (m, mat, 16); }
    
        Matrix4() {}
    
        float m[4][4];
    };
    
    void foo(Matrix4 mat)
    { }
    
    int main()
    {
        float m[4][4];
        Matrix4 matProj(m);
        foo(m);
    }
    So change the code above to something that duplicates the error and will compile on everyone's system without having to introduce directX types or mystery functions that no one knows about.

    Regards,

    Paul McKenzie

  9. #9
    Join Date
    Oct 2008
    Posts
    1,164

    Re: Writing a simple copy constructor

    moreover, note that the parameter "mat" in "Matrix4(float mat[4][4])" does not have type float[4][4] as you might think. Its type is float(*)[4]; this means that you can pass an array float[1][4], float[3][4], etc... to that constructor without any complaint from the compiler but with disastrous effects at runtime.
    If you want type checking either pass by reference-to-array or properly write a copy constructor, as suggested by Paul.

  10. #10
    Join Date
    Dec 2010
    Posts
    646

    Re: Writing a simple copy constructor

    I'd like to pass it as reference-to-array
    But I can't do this
    Matrix(const float& mat[][4])
    which is a syntax error
    Last edited by lucky6969b; December 10th, 2012 at 05:53 AM.

  11. #11
    Join Date
    Apr 1999
    Posts
    27,444

    Re: Writing a simple copy constructor

    Quote Originally Posted by lucky6969b View Post
    I'd like to pass it as reference-to-array
    But I can't do this
    Matrix(const float& mat[][4])
    which is a syntax error
    Instead of messing around with naked, dumb arrays, use std::array and you get no issues:
    Code:
    #include <array>
    
    // use std::array if using a more modern compiler instead of std::tr1::array
    typedef std::tr1::array<float, 4> Float1D;    
    typedef std::tr1::array<Float1D, 4> Float2D;
    
    class Matrix4
    {
    public:
    
        Matrix4(Float2D& mat) : m(mat)
        { }
        Matrix4() {}
        Float2D m;
    };
    
    int main()
    {
        Float1D m1;
        Float2D m;
        m1.assign(10);  // set the array up here
        m.assign(m1);
        Matrix4 matProj(m);
    }
    This solves the issue of passing by reference, and also addresses the disastrous effects if somewhere in your code you have declared anything but 4 rows and you inadvertently pass it to your functions. The std::array class is a lightweight STL class that wraps an array declaration. So all that's done is to create an array of an array.

    If your Matrix class only consists of a 4x4 float array, all you really need is std::array as outlined above, and just typedef it to Matrix4.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; December 10th, 2012 at 08:43 AM.

  12. #12
    Join Date
    Dec 2010
    Posts
    646

    Re: Writing a simple copy constructor

    But How do you assign values to individual elements?
    m1.assign(10); // set the array up here
    Thanks
    Jack

  13. #13
    Join Date
    Apr 1999
    Posts
    27,444

    Re: Writing a simple copy constructor

    Quote Originally Posted by lucky6969b View Post
    But How do you assign values to individual elements?
    Just like an array using [].
    Code:
    m1[0] = 6;
    Regards,

    Paul McKenzie

  14. #14
    Join Date
    Dec 2010
    Posts
    646

    Re: Writing a simple copy constructor

    Thanks Paul. It's all great!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center