Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Jul 1st, 2008, 10:16 PM   #1
titaniumdecoy
Expert Programmer
 
titaniumdecoy's Avatar
 
Join Date: Nov 2005
Posts: 843
Rep Power: 3 titaniumdecoy is on a distinguished road
Send a message via AIM to titaniumdecoy
error: passing as 'this' discards qualifiers

Another C++ question.

I am trying to write a Board class so that I can access pieces in an internal Piece *pieces[8][8]; structure using index operators. I have a helper class Board::PieceDict which is constructed with a pointer to a particular row of pieces so that I can get a particular piece by writing Board b; Piece& p = b[0][0];.

Here is my implementation of Board::operator[]:

const Board::PieceDict& Board::operator[] (unsigned int x) 
{
    PieceDict *pd = new PieceDict(pieces[x]);
    return *pd;
}

When I call, on a line by itself, board[0]; I get this error:

Board.c: In function ‘std::ostream& ChessGame::operator<<(std::ostream&, const ChessGame::Board&)’:
Board.c:44: error: passing ‘const ChessGame::Board’ as ‘this’ argument of ‘const ChessGame::Board::PieceDict& ChessGame::Board::operator[](unsigned int)’ discards qualifiers
make: *** [Board.o] Error 1

Any advice is appreciated.

Also, is there a way to automatically free the PieceDict object that will only be used temporarily?
titaniumdecoy is offline   Reply With Quote
Old Jul 1st, 2008, 10:57 PM   #2
titaniumdecoy
Expert Programmer
 
titaniumdecoy's Avatar
 
Join Date: Nov 2005
Posts: 843
Rep Power: 3 titaniumdecoy is on a distinguished road
Send a message via AIM to titaniumdecoy
Re: error: passing as 'this' discards qualifiers

Got it. It turns out the Board::operator[] function didn't appreciate being called on a const Board& since the former did not have a suffix of const. I hate the cryptic error messages that the C++ compiler generates.

My last question remains unanswered:
Quote:
Originally Posted by titaniumdecoy View Post
Also, is there a way to automatically free the PieceDict object that will only be used temporarily?
I am not sure how to deal with deleting the 'new' object returned by board[i] since I intend to use the object in a statement like if (board[i][j] == NULL).

EDIT: Almost all of the problems I have encountered so far have come from a) #includeing a file that should (not) have been included, or b) declaring functions/parameters/return values as const that should not have been declared as such. Are there definitive rules for dealing with these issues?

Last edited by titaniumdecoy; Jul 1st, 2008 at 11:12 PM.
titaniumdecoy is offline   Reply With Quote
Old Jul 2nd, 2008, 3:54 AM   #3
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,207
Rep Power: 5 grumpy is on a distinguished road
Re: error: passing as 'this' discards qualifiers

Why do you have operator[], which returns a const reference, creating a new object? You could also simply do this;
const Board::PieceDict& Board::operator[] (unsigned int x) const
{
    return pieces[x];
}
The additional const qualifier also allows the operator [] to be used for a const Board object. No need to worry about releasing dynamically created objects.
grumpy is offline   Reply With Quote
Old Jul 2nd, 2008, 12:47 PM   #4
titaniumdecoy
Expert Programmer
 
titaniumdecoy's Avatar
 
Join Date: Nov 2005
Posts: 843
Rep Power: 3 titaniumdecoy is on a distinguished road
Send a message via AIM to titaniumdecoy
Re: error: passing as 'this' discards qualifiers

I get this error:

Board.c: In member function ‘const ChessGame::Board::PieceDict& ChessGame::Board::operator[](unsigned int) const’:
Board.c:23: error: invalid initialization of reference of type ‘const ChessGame::Board::PieceDict&’ from expression of type ‘ChessGame::Piece* const*’

I got it to work as follows, although I'm not sure whether it is a better/worse solution:

ChessGame::Board::PieceDict ChessGame::Board::operator[] (unsigned int x)
{
	return pieces[x];
}

When I try to add a suffix of const to the function, it doesn't compile. I think this is because pieces is being passed as a non-const reference to the constructor of PieceDict. I don't know whether I should try to change everything to const, since eventually I want to return the underlying Piece* and it seems like that would require a const_cast.
titaniumdecoy is offline   Reply With Quote
Old Jul 3rd, 2008, 5:01 AM   #5
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,207
Rep Power: 5 grumpy is on a distinguished road
Re: error: passing as 'this' discards qualifiers

Quote:
Originally Posted by titaniumdecoy View Post
When I try to add a suffix of const to the function, it doesn't compile. I think this is because pieces is being passed as a non-const reference to the constructor of PieceDict.
By this, I assume you mean that pieces is not an array of PieceDict (i.e. piece[x] is not a PieceDict so one needs to be constructed from piece[x]).

This means PieceDict needs a constructor of the form
   PieceDict(const WhateverTypeThePieceArrayElementsAre &);
and the operator[] should not return a reference (returning a reference to a temporary from a function can cause the caller to give undefined results, as that temporary will no longer be guaranteed to exist.

The alternative is to change the operator[] so it is of the form;
    const WhateverTypeThePieceArrayElementsAre  &operator[](unsigned int) const;
Quote:
Originally Posted by titaniumdecoy View Post
I don't know whether I should try to change everything to const, since eventually I want to return the underlying Piece* and it seems like that would require a const_cast.
Depends on what you want to do with that "underlying Piece*". If you need to change it, then it should not be returned as a const.

However, you're the one who is having trouble with discarding const: that means you have something declared const, but you are attempting to return it as a non-const which (implicitly) will allow that const thing to be changed.

In short, you need to make up your mind.

Making a non-static member function const is a declaration that the function will not change the object it acts on. It is not allowed to do any operation that permits changing that object (eg passing it by non-const reference to another function, calling a non-const member function, etc).

A compiler complaining about discarding const means that you have something the compiler considers const, but your are forcing the compiler to consider it as non-const.
grumpy is offline   Reply With Quote
Old Jul 3rd, 2008, 12:28 PM   #6
titaniumdecoy
Expert Programmer
 
titaniumdecoy's Avatar
 
Join Date: Nov 2005
Posts: 843
Rep Power: 3 titaniumdecoy is on a distinguished road
Send a message via AIM to titaniumdecoy
Re: error: passing as 'this' discards qualifiers

That makes sense, thanks.
titaniumdecoy is offline   Reply With Quote
Old Jul 3rd, 2008, 3:01 PM   #7
titaniumdecoy
Expert Programmer
 
titaniumdecoy's Avatar
 
Join Date: Nov 2005
Posts: 843
Rep Power: 3 titaniumdecoy is on a distinguished road
Send a message via AIM to titaniumdecoy
Re: error: passing as 'this' discards qualifiers

This is probably a stupid question, but I can't get it to work.

std::ostream& operator<< (std::ostream& os, const ChessGame::Board& board);

When I add the const (in bold) keyword to the function above, I can no longer print a non-const Board. This seems wrong, since the function does not change Board. This is the error I get:

Undefined symbols:
  "ChessGame::operator<<(std::basic_ostream<char, std::char_traits<char> >&, ChessGame::Board&)", referenced from:
      _main in Chess.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [chess] Error 1
titaniumdecoy is offline   Reply With Quote
Old Jul 3rd, 2008, 8:14 PM   #8
titaniumdecoy
Expert Programmer
 
titaniumdecoy's Avatar
 
Join Date: Nov 2005
Posts: 843
Rep Power: 3 titaniumdecoy is on a distinguished road
Send a message via AIM to titaniumdecoy
Re: error: passing as 'this' discards qualifiers

Turns out it was just a problem with my Makefile.
titaniumdecoy is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 3:38 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC