Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

operator overload: incompatible type and too many params

Posted on 2016-10-27
5
Medium Priority
?
144 Views
Last Modified: 2016-10-29
I'm trying to overload operators in C++11 in a simple class.  I have the following (partial) class defined:
//Board.h
public class Board {
public:
	Board();
	bool isEmpty(int,int);
	void setCell(int, int,bool);
	bool getCell(int, int);

	void operator= (const Board &b) {};
	inline bool operator==(const Board& lhs, const Board& rhs) {return false;};
}

//Board.cpp
void Board::operator= (const Board &b) {
	for (int r = 1; r <= ROWS; ++r) {
		for (int c = 1; c <= COLS; ++c) {
			b.isEmpty(r,c);
//			setCell(r, c, b.getCell(r,c));
		}
	}
};

Open in new window

Lines 9 & 10 (in Board.h) is where I'm encountering problems.  The line 10 function is inline, and empty currently, and the line 9 function (operator=) is below in Board.cpp.  For operator= I'm getting this error on line 17:
error C2662: 'bool Board::isEmpty(int,int)' : cannot convert 'this' pointer from 'const Board' to 'Board &'

Open in new window

I'm just calling the isEmpty function on the input Board, which doesn't modify anything.

With "operator==", I get the error:
error C2804: binary 'operator ==' has too many parameters

Open in new window

Operator== needs two parameters, right?  I got this code off a tutorial site and just changed the class from 'X' to 'Board'.

I feel like these two errors are related, though I tried compiling them separately and both failed.  What am I doing wrong?
Thanks!
0
Comment
Question by:ugeb
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
5 Comments
 
LVL 31

Accepted Solution

by:
Zoppo earned 1200 total points
ID: 41862639
Hi ugeb,

first you call isEmpty (which is not declared as const) of the const instance b. To resolve this just declare and implement isEmpty as const, i.e.:
bool isEmpty(int,int) const;

Open in new window


Next: == operator as class member doesn't need two parameters, it only needs one parameter which in the function is compared with the this-instance. Beside this you can implement a global == operator outside of the class, in this case you need two parameters.

At last a hint: a = operator should always return a reference to this in order to allow statements like a=b=c; - i.e.:
...
Board& operator= (const Board &b);
...
Board& Board::operator= (const Board &b) {
	for (int r = 1; r <= ROWS; ++r) {
		for (int c = 1; c <= COLS; ++c) {
			b.isEmpty(r,c);
//			setCell(r, c, b.getCell(r,c));
		}
	}
	return *this;
};

Open in new window

Hope this helps,

ZOPPO
1
 
LVL 11

Author Comment

by:ugeb
ID: 41862967
Hi Zoppo,

Thank you for the clarification. I tried it and realized that I had to const not just the isEmpty function, but also functions that were called from isEmpty, even though they didn't have the board as their parameter!  Seems like I would have to do a const_cast to avoid that domino effect.

Thank you for the tip on returning the *this reference. I wonder, though, how you would treat operator+ then?  It would need to return a copy, not a reference.  If I then return a copy from a new operation, do I need to worry about memory leaks?
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 41863451
Hi again,

you should try to avoid removing const anywhere using a const_cast. A function which is called isEmpty shouldn't need to anyhow modify the object so declaring it const should be possible.

The rules for the const-ness are quite simple: You can only call functions which are declared as const with a const instance. From within a member function which is declared as const you can only call other member functions which are declared as const too.

It is highly recommended to declare functions as const which are not expected to modify the object. In you code IMO even getCell and == operator should be declared as const since from their names they're not expected to modify any members.

And about the return *this; as reference: AFAIK it would even be possible to return *this when the return value is not declared to be a reference, I think even then a=b=c should work, but in this case i.e. b=c will create a copy (when the operator == returns an instance) using the copy constructor - now it's often the case copy constructors are implemented in a way they simply call the assignment operator, so this would lead to infinite loops. With operator + this is not a problem so returning the result by value is ok, memory leaks should be avoided in copy constructor and/or assignment operator.

ZOPPO
1
 
LVL 35

Assisted Solution

by:sarabande
sarabande earned 800 total points
ID: 41863682
you can implement a global == operator outside of the class, in this case you need two parameters.
fyi, you also could define a 'friend' global operator== with two arguments within the class. this has the Advantage that the members of the class can be accessed without getters.

class Board
{
     ...
     friend Board & operator==(const Board & b1, const Board & b2)
     {
            ...
            return *this;
     };
};

Open in new window


I would have to do a const_cast to avoid that domino effect
as the usage of const is an optional thing you were doing to have safer code, using a const_cast is a kind of betraying yourself and it is always a miserable design. as Zoppo has told, nobody would expect that calling IsEmpty() function would modifiy the object. from a designer's view IsEmpty neither should have arguments. you were passing two integers to Board::IsEmpty? does that mean the IsEmpty checks the two arguments whether they were "empty". if so, why it is a member of class Board?


I wonder, though, how you would treat operator+ then?  It would need to return a copy, not a reference.  If I then return a copy from a new operation, do I need to worry about memory leaks?
the operator+=  would also return *this, same as operator=. the operator+ would not, even if you could do it. return *this in operator+ actually is a severe design error. operator+ should be const and definitively need to return the result by value.

if a function returns by value, the result is a tempory which is alive until the next block end }. you don't have to care for leaks. if you return *this you were returning a reference to an existing object which doesn't allocate any extra memory (and therefore never leaks). the greater risk with return values is that you were returning references or pointers of local objects. after the function call, the pointers are invalid and in most cases it would crash sooner or later.

Sara
1
 
LVL 11

Author Closing Comment

by:ugeb
ID: 41865435
Thank you both.  I've not used operator overloading much and so I'm having to learn it, and your comments are very useful.  Thanks again!
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Article by: evilrix
Looking for a way to avoid searching through large data sets for data that doesn't exist? A Bloom Filter might be what you need. This data structure is a probabilistic filter that allows you to avoid unnecessary searches when you know the data defin…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

618 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question