CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 21

Thread: const Class& class

  1. #1
    Join Date
    Jan 2009
    Posts
    25

    const Class& class

    friend ostream& operator<<(ostream& output, const Matrix& matrix)

    Error 2 error C2662: 'Matrix<T>::YDim' : cannot convert 'this' pointer from 'const Matrix<T>' to 'Matrix<T> &'

    I seem to get the same error for all of the functions I'm defining with a const Matrix& matrix, but when I remove the const it works fine.

    Thanks in advance!

  2. #2
    Join Date
    Aug 2005
    Location
    San Diego, CA
    Posts
    1,054

    Lightbulb Re: const Class& class

    Well what is the Matrix class? Post the class declaration? Is this a template class? Someone might recognize the error and have an epiphany but it is always better to post enough code so that other people can drag and drop the text into a file and compile it themselves.

  3. #3
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: const Class& class

    ...
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  4. #4
    Join Date
    May 2002
    Posts
    1,435

    Re: const Class& class

    Most likely cause is YDim needs to be declared const:

    Matrix<T>::YDim() const
    {
    }

  5. #5
    Join Date
    Jan 2009
    Posts
    25

    Re: const Class& class

    Sorry about that....

    template <typename T>
    class Matrix
    {
    private:
    T** mMatrix;
    T mValue;

    public:
    Matrix(size_t pRows, size_t pCols, const T& value)
    {
    size_t i, j; // General purpose loop variables

    mValue = value;

    mMatrix = new T* [pRows+1]; ; // Allocate rows

    for(i=0; i<pRows; i++)
    mMatrix[i] = new T[pCols+1]; // Allocate columns
    mMatrix[i] = new T[1]; // Allocate sentinel row

    // initialize mMatrix
    for(i=0; i<pRows; i++)
    {
    size_t j;
    for(j=0; j<pCols; j++)
    mMatrix[i][j] = value; // initialize column with value
    mMatrix[i][j] = (T) -1; // Add sentinel to end of column
    }
    mMatrix[i][0] = (T) -1; // Add sentinel to last row

    }

    ~Matrix() { Destroy(); }

    void Destroy()
    {
    for(size_t y=0; y<YDim(); y++)
    {
    delete mMatrix[y];
    mMatrix[y]=0;
    }

    delete mMatrix;
    mMatrix=0;
    }


    size_t& YDim()
    {
    size_t i=-1; // General purpose loop variables

    if(mMatrix!=0)
    for(i=0; mMatrix[i]!=0;i++)
    if(mMatrix[i][0]== (T) -1) break;

    return i;
    }

    size_t& XDim()
    {
    size_t j=-1; // General purpose loop variables

    if(YDim()>0)
    for(j=0; mMatrix[0][j] != (T) -1; j++);

    return j;
    }


    T operator()(size_t row, size_t col)
    {
    return mMatrix[row][col];
    }


    bool ResetRow(size_t row)
    {
    return ResetRowTo(row, mValue);
    }

    bool ResetRowTo(size_t row, T value)
    {
    if(YDim()!=-1 && row<YDim())
    {
    for(size_t j=0; mMatrix[row][j] != (T) -1; j++)
    mMatrix[row][j] = value;

    return 1;
    }
    else
    return 0;
    }

    friend ostream& operator<<(ostream& output, Matrix& matrix)
    {
    for(size_t y=0; y<matrix.YDim(); y++)
    {
    for(size_t x=0; x<matrix.XDim(); x++)
    {
    cout << matrix(y,x) << " ";
    }
    cout << endl;
    }

    return output;
    }



    };

  6. #6
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: const Class& class

    If the function accepts 'matrix' as a const reference then it is not allowed to modify it. XDim & YDim members are not 'const' and therefore are not allowed to be called here, as they do not promise not to change the class.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  7. #7
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: const Class& class

    please use [code][/code] tags when posting code.

    You have a number of problems here. Remove the ampersand highlighted in bold since you are attempting to reference a function local variable that is popped of the stack when the function returns (this constitutes undefined behaviour), therefore you should return by value.

    Code:
    size_t& YDim()
      {
        size_t i=-1; // General purpose loop variables
    
        if(mMatrix!=0)
          for(i=0; mMatrix[i]!=0;i++)
            if(mMatrix[i][0]== (T) -1) break;
    
        return i;
      }
    Also make the function into a const function i.e.
    Code:
    size_t YDim() const
      {
        size_t i=-1; // General purpose loop variables
    
        if(mMatrix!=0)
          for(i=0; mMatrix[i]!=0;i++)
            if(mMatrix[i][0]== (T) -1) break;
    
        return i;
      }
    Repeat the above two steps for XDim.

    Also, you should modify your operator() function by adding the ampersand highlighted in bold since users of your class would intitively expect it to return by reference, so they can modify the value in the array:

    Code:
    T& operator()(size_t row, size_t col)
      {
        return mMatrix[row][col];
      }
    You also need to add a const function version of the above:

    Code:
    T operator()(size_t row, size_t col) const
      {
        return mMatrix[row][col];
      }
    Note that the return of the const version purposely returns by value, alternatively you can return by const reference.
    Last edited by PredicateNormative; January 14th, 2009 at 12:56 PM. Reason: gramma

  8. #8
    Join Date
    Aug 2005
    Location
    San Diego, CA
    Posts
    1,054

    Re: const Class& class

    I agreed with 0xC0000005 when I read his post but this code compiled fine for me even without declaring the functions const. That is odd. I didn't expect this to compile. I'm using a green hills c++ compiler.

    Code:
    template <typename T>
    class Matrix
    {
    private:
        T** mMatrix;
        T mValue;
    
    public:
        Matrix(size_t pRows, size_t pCols, const T& value)
        {
    	size_t i, j; // General purpose loop variables
    
    	mValue = value;
    
    	mMatrix = new T* [pRows+1]; ; // Allocate rows
    
    	for(i=0; i<pRows; i++)
    	    mMatrix[i] = new T[pCols+1]; // Allocate columns
    	mMatrix[i] = new T[1]; // Allocate sentinel row
    
    // initialize mMatrix
    	for(i=0; i<pRows; i++)
    	{
    	    size_t j;
    	    for(j=0; j<pCols; j++)
    		mMatrix[i][j] = value; // initialize column with value
    	    mMatrix[i][j] = (T) -1; // Add sentinel to end of column
    	}
    	mMatrix[i][0] = (T) -1; // Add sentinel to last row
    
        }
    
        ~Matrix() { Destroy(); }
    
        void Destroy()
        {
    	for(size_t y=0; y<YDim(); y++)
    	{
    	    delete mMatrix[y];
    	    mMatrix[y]=0;
    	}
    
    	delete mMatrix;
    	mMatrix=0;
        }
    
    
        size_t& YDim()
        {
    	size_t i=-1; // General purpose loop variables
    
    	if(mMatrix!=0)
    	    for(i=0; mMatrix[i]!=0;i++)
    		if(mMatrix[i][0]== (T) -1) break;
    
    	return i;
        }
    
        size_t& XDim()
        {
    	size_t j=-1; // General purpose loop variables
    
    	if(YDim()>0)
    	    for(j=0; mMatrix[0][j] != (T) -1; j++);
    
    	return j;
        }
    
    
        T operator()(size_t row, size_t col)
        {
    	return mMatrix[row][col];
        }
    
    
        bool ResetRow(size_t row)
        {
    	return ResetRowTo(row, mValue);
        }
    
        bool ResetRowTo(size_t row, T value)
        {
    	if(YDim()!=-1 && row<YDim())
    	{
    	    for(size_t j=0; mMatrix[row][j] != (T) -1; j++)
    		mMatrix[row][j] = value;
    
    	    return 1;
    	}
    	else
    	    return 0;
        }
    
        friend ostream& operator<<(ostream& output, const Matrix& matrix)
        {
    	for(size_t y=0; y<matrix.YDim(); y++)
    	{
    	    for(size_t x=0; x<matrix.XDim(); x++)
    	    {
    		cout << matrix(y,x) << " ";
    	    }
    	    cout << endl;
    	}
    
    	return output;
        }
    
    
    
    };
    Last edited by kempofighter; January 14th, 2009 at 12:36 PM. Reason: clarification.

  9. #9
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: const Class& class

    In addition to my above comments, the lack of std:: before ostream in your operator<< function suggests that you are writing using namespace std; in your header file, and you shouldn't do this in your header file, since you may cause namespace clashes in any other code that is included in your compilation.

    You seem to have some issues with your loop variables. You declare a loop variable j in your constructor, but do not use it, prefering to declare a second local j inside your initialise matrix for loop. You should get into the habit of initialising your variables.

    Finally, the following code found in your constructor:

    Code:
    for(i=0; i<pRows; i++)
        mMatrix[i] = new T[pCols+1]; // Allocate columns
    mMatrix[i] = new T[1]; // Allocate sentinel row
    Once your for loop finishes, you fail to increment i before assigning a new memory allocation to [I]mMatrix - this constitutes a memory leak.

    You could change the above to

    Code:
    for(i=0; i<pRows; i++)
        mMatrix[i] = new T[pCols+1]; // Allocate columns
    mMatrix[++i] = new T[1]; // Allocate sentinel row
    Last edited by PredicateNormative; January 14th, 2009 at 12:57 PM. Reason: Added: You should get into the habit of initialising your variables.

  10. #10
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: const Class& class

    Quote Originally Posted by kempofighter View Post
    I agreed with 0xC0000005 when I read his post but this code compiled fine for me even without declaring the functions const. That is odd. I didn't expect this to compile. I'm using a green hills c++ compiler.
    Perhaps you forgot to print the matrix e.g? :

    Code:
    Matrix<int> m(5,5,0);
    std::cout << m << std::endl;
    If you don't use the operator<< function, the compiler is allowed to exclude it from the compilation.

  11. #11
    Join Date
    Aug 2005
    Location
    San Diego, CA
    Posts
    1,054

    Re: const Class& class

    Quote Originally Posted by PredicateNormative View Post
    Perhaps you forgot to print the matrix e.g? :

    If you don't use the operator<< function, the compiler is allowed to exclude it from the compilation.
    Good point, I tried exactly that but got a compiler error. I've never overloaded the << operator before so I didn't understand why *that* didn't compile.
    Code:
    int main ()
    {
           
        Matrix<int> m(5,5,0);
        std::cout << m << std::endl;
    
        return 0;
    }
    
    error #349: no operator "<<" matches these operands
                operand types are: std::ostream << Matrix<int>
          std::cout << m << std::endl;
    I thought that the overloaded << was supposed to make that work. If I comment out the cout, the class declaration compiles (for the reason your are specifying most likely). But if I try to use the stream operator as you suggest I get this other error instead. Also, in the previous block of code that I posted I changed the input arg to non-const just to see if that line in the main function would compile that uses the overloaded <<.

    Good point on the other comments. I saw similar things and the class decl does produce quite a few warnings but you have already pointed those things out. I wonder how you are able to compile that simple main function but I am not. Weird.

  12. #12
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: const Class& class

    What line is it complaining about? Have you made sure that all standard objects have std:: before them, or have you used the non-ideal solution by adding using namespace std?
    Last edited by PredicateNormative; January 15th, 2009 at 03:55 AM.

  13. #13
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: const Class& class

    If you have done the above, then thinking about it, the problem is probably that technically:

    Code:
    template <typename T>
    class Matrix
    {
         //...
    
         friend ostream& operator<<(ostream& output, const Matrix& matrix)
        {
          for(size_t y=0; y<matrix.YDim(); y++)
          {
            for(size_t x=0; x<matrix.XDim(); x++)
            {
              std::cout << matrix(y,x) << " ";
            }
            std::cout << std::endl;
          }
          return output;
        }
    
    };
    is incorrect, and should be

    Code:
    template <typename T>
    class Matrix
    {
         //...
         template <typename U>
         friend std::ostream& operator<<(std::ostream& output, const Matrix<U>& matrix);
    
    };
    
    template <typename U>
    std::ostream& operator<<(std::ostream& output, const Matrix<U>& matrix)
    {
        for(size_t y=0; y<matrix.YDim(); y++)
         {
            for(size_t x=0; x<matrix.XDim(); x++)
            {
               std::cout << matrix(y,x) << " ";
            }
            std::cout << std::endl;
         }
         return output;
    }

  14. #14
    Join Date
    Aug 2005
    Location
    San Diego, CA
    Posts
    1,054

    Lightbulb Re: const Class& class

    Thanks predicate, I was wondering about that declaration. However, the compiler error didn't change at all. Then I noticed something awfully strange about that overloaded << operator function. Something about it isn't correct.

    The OP defined the function within the class which is incorrect. It needs to be declared as a friend but defined globally.

    Also, the OP uses cout within the definition. That is also wrong. He needs to be doing it like this:

    Code:
    template <typename T>
    class Matrix
    {
    // ... declaration of class
    
    // declare the globally defined function to be a friend but don't define it
    // in the class.  Actually i don't think that this is necessary since the 
    // function uses Matrix's public interface but this is the pattern I see 
    // when studying existing code.  I guess that this is done so that the
    // function definition can directly access private/protected members.
    template <typename T>
        friend ostream& operator<<(ostream& output, Matrix<T>& matrix);
    };
    
    // (U) Define the function globally
    template <typename T>
    ostream& operator<<(ostream& output, Matrix<T>& matrix)
    {
    	for(size_t y=0; y<matrix.YDim(); y++)
    	{
    	    for(size_t x=0; x<matrix.XDim(); x++)
    	    {
                  // (U) Stream to output not cout
    		output << matrix(y,x) << " ";
    	    }
                // (U) Stream to output not cout
    	    output << std::endl;
    	}
    
    	return output;
        }
    Well anyway, making those fixes seemed to work. The program compiled and printed a matrix full of zeroes. There are other warnings and problems with the program but at least those changes allowed the stream operator to work.

  15. #15
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: const Class& class

    Perhaps you should re-read the end of post #13

Page 1 of 2 12 LastLast

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




On-Demand Webinars (sponsored)