Thread: equal operator problems

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    57

    equal operator problems

    Not sure why i have this error or if im going about this operator right.

    I also cant seem to split this filer into a header and source without errors.

    Thanlks

    position.h:85: error: ‘Position<Type> operator=(Position<Type>&) [with Type = int]’ must be a nonstatic member function
    position.h:85: error: ‘Position<Type> operator=(Position<Type>&) [with Type = int]’ must take exactly two arguments

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    If you're going to make a friend function it shouldn't be a member of a class per se. A friend function is by definition a nonmember function that has access to a class' private members. -shudders at the poor word choice-

    You have to include it when you declare the class, yes, but that's only so the class knows it has a friend in the first place. The implementation is totally different. You need to pass in references for both sides of the assignment operator in order for it to work.

    Also you should compare the two arguments and make sure they aren't the same, and if they are, then you can save a lot of time by just returning the left-hand object.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Just an offhand comment: your operator+, operator-, operator*, operator/ and operator== all do not modify their arguments, so the arguments should be passed as const reference. The getter functions should then be declared as const member functions.

    As citizen mentioned, your copy assignment operator should not be a friend. It too should take its argument as a const reference, and should return a reference. In principle, it should make a copy of the argument passed, not copy the argument passed to some temporary that is returned.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> I also cant seem to split this filer into a header and source without errors.

    It's a templated class. It all goes into the header file.

  5. #5
    Registered User
    Join Date
    May 2006
    Posts
    57
    Ok, found a much better explaination of this stuff online (my book is crap for this...).

    Now I have a new error that confuses me
    test.cpp:11: error: no match for ‘operator=’ in ‘c = a. Position<Type>:perator+ [with Type = int](((Position<int>&)(& b)))’
    position.h:59: note: candidates are: const Position<Type>& Position<Type>:perator=(Position<Type>&) [with Type = int]
    Thanks guys

  6. #6
    The Richness... Richie T's Avatar
    Join Date
    Jan 2006
    Location
    Ireland
    Posts
    469
    Please don't ever post code in that manner again unless you're
    sure you can prevent it from becoming mangled - I spent 15 mins
    putting it back together and it was missing a couple of keywords.
    Declaring a template class looks like this:

    Code:
    template <class Type> Position
    {
    .
    .
    .
    };
    then creating instances looks like this:

    Code:
    Position <int> a(1,2,3);
    Anyways, to the problem at hand. This is the offending line of
    code from the compilers viewpoint:

    c = (a + b);

    Lets look at your + operator:

    Code:
    	const void operator + (Position &rhs)
    	{
    		setX( getX() + rhs.getX() );
    		setY( getY() + rhs.getY() );
    		setZ( getZ() + rhs.getZ() ); 
    	}
    now what this code does is that it takes the left operand (a),
    uses its setter functions to change its private attributes to
    the sum of the current values and the parameter class instance
    (thereby modifying the (a) instance of the class), and returns a
    void.

    then your assignment operator (=) is expecting a class of type
    Postion as the right hand operand - you are sending it a void.

    to fix it all,

    the + operator shouldn't manipulate either object. change it
    to this:

    Code:
    	Position operator + (Position &rhs)
    	{
                    Position temp;
    		temp.x = x + rhs.x;
    		temp.y = y + rhs.y;
    		temp.z = z + rhs.z;
    
    		return temp;
    	}
    this is legal because all instances of the same class type are
    essentially friends with eachother - there's no need to use the
    getters and setters. You can do the same for your other functions

    [update]
    one I fixed that, i got errors relating to your copy constructor.
    change it to this:

    Code:
    	Position(const Position &rhs)
    	{
    		setX( rhs.x ); 
    		setY( rhs.y ); 
    		setZ( rhs.z );
    	}
    [/update]
    Last edited by Richie T; 05-19-2006 at 07:49 PM.
    No No's:
    fflush (stdin); gets (); void main ();


    Goodies:
    Example of fgets (); The FAQ, C/C++ Reference


    My Gear:
    OS - Windows XP
    IDE - MS Visual C++ 2008 Express Edition


    ASCII stupid question, get a stupid ANSI

  7. #7
    Registered User
    Join Date
    May 2006
    Posts
    57
    Sorry about the formatting.

    It still doesnt seem to like my equal operator.

    test.cpp:11: error: no match for ‘operator=’ in ‘c = Position<Type>:perator+(Position<Type>&) [with Type = int](((Position<int>&)(& b)))’
    position.h:61: note: candidates are: const Position<Type>& Position<Type>:perator=(Position<Type>&) [with Type = int]
    Thanks alot

    Heres all the code:

    test.c
    Code:
    #include <iostream>
    using namespace std;
    
    #include "position.h"
    
    int main() {
    	Position <int> a(1,2,3);
    	Position <int> b(5,5,5);
    	Position <int> c;
    
    	c = (a + b);
    
    	cout << c.getX() << endl;
    	cout << c.getY() << endl;
    	cout << c.getZ() << endl;
    
    	return 0;
    }
    position.h
    Code:
    #ifndef _POSITION_H_
    #define _POSITION_H_
    
    template <class Type> class Position {
    	public:
    		//
    		// Constructors
    		//
    		Position() {				// 0d
    			set(0, 0, 0);
    		}
    
    		Position(Type X) {			// 1d
    			set(X, 0, 0);
    		}
    
    		Position(Type X, Type Y) {		// 2d
    			set(X, Y, 0);
    		}
    
    		Position(Type X, Type Y, Type Z) {	// 3d
    			set(X, Y, Z);
    		}
    
    		Position(const Position &rhs) {		// Copy constructor
    			setX( rhs.x ); 			
                    	setY( rhs.y ); 
                    	setZ( rhs.z );
    		}
    
    		//
    		// Operators
    		//
    		Position operator + (Position <Type> &rhs) {
    			Position <Type> tmp;
    
    			tmp.setX( getX() + rhs.getX() );
    			tmp.setY( getY() + rhs.getY() );
    			tmp.setZ( getZ() + rhs.getZ() );
    
    			return tmp;
    		}
    
    		const bool operator == (Position &rhs) {
    			if(getX() != rhs.getX()) {
    				return false;
    			}
    
    			if(getY() != rhs.getY()) {
    				return false;
    			}
    
    			if(getZ() != rhs.getZ()) {
    				return false;
    			}
    
    			return true;
    		}
    
    		const Position& operator = (Position <Type> &rhs) {
    			if (this != &rhs) {
    				setX( getX() + rhs.getX() );
    				setY( getY() + rhs.getY() );
    				setZ( getZ() + rhs.getZ() );
    			}
    
    			return *this;
    		}
    
    		//
    		// Set position - 1d
    		//
    		void set(Type X) {	// If a dimension isnt specified
    			setX(X);	// X will be used.
    		}
    
    		void setX(Type X) {
    			x = X;
    		}
    
    		void setY(Type Y) {
    			y = Y;
    		}
    
    		void setZ(Type Z) {
    			z = Z;
    		}
    
    		//
    		// Set position - 2d
    		//
    		void set(Type X, Type Y) {
    			setX(X);
    			setY(Y);
    		}
    
    		//
    		// Set position - 3d
    		//
    		void set(Type X, Type Y, Type Z) {
    			setX(X);
    			setY(Y);
    			setZ(Z);
    		}
    
    		//
    		// Get position
    		//
    		const Type get() {		// If a dimension isnt specified
    			return getX();		// X will be used.
    		}
    
    		const Type getX() {
    			return x;
    		}
    
    		const Type getY() {
    			return y;
    		}
    
    		const Type getZ() {
    			return z;
    		}
    
    		//
    		// General
    		//
    		virtual void reset() {
    			set(0, 0, 0);
    		}
    
    	private:
    		Type x;
    		Type y;
    		Type z;
    };
    
    #endif

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    From what I see, you can leave out writing the copy constructor and copy assignment operator as the compiler generated version should suffice. This would solve your "compiler doesnt seem to like my equal operator" problem since the compiler would be generating it for you.

    I am not too sure of this, but you should also be able to condense your other constructors to a single one:
    Code:
    Position(const Type& X = 0, const Type& Y = 0, const Type& Z = 0) : x(X), y(Y), z(Z) {}
    Write a member operator+= that takes a const reference and returns a reference. The addition logic would then be implemented in this operator+=
    Implement a non-member non-friend operator+ that uses operator+= to actually do the addition.
    An example would be:
    Code:
    Position operator+(const Position& lhs, const Position& rhs) {
    	return Position(lhs) += rhs;
    }
    Make operator== a non-member (non-friend too, since you have getter functions) function of the class. It would probably have the prototype:
    Code:
    bool operator == (const Position& lhs, const Position& rhs);
    The implementation may be something like:
    Code:
    return (lhs.getX() == rhs.getX()) && (lhs.getY() == rhs.getY()) && (lhs.getZ() == rhs.getZ());
    Make your getter functions const, e.g.
    Code:
    const Type getX() const {
    	return x;
    }
    Oh, and by the way, identifiers beginning with an underscore followed by an uppercase character are reserved to the implementation. This means that you may want to change:
    Code:
    #ifndef _POSITION_H_
    #define _POSITION_H_
    To say:
    Code:
    #ifndef POSITION_H_
    #define POSITION_H_
    Last edited by laserlight; 05-19-2006 at 10:44 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Equal compare
    By George2 in forum C Programming
    Replies: 1
    Last Post: 11-10-2007, 05:26 AM
  2. compare if 2 string types are equal
    By sujeet1 in forum C++ Programming
    Replies: 4
    Last Post: 06-06-2007, 06:37 PM
  3. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  4. set string array equal variable
    By WaterNut in forum C++ Programming
    Replies: 3
    Last Post: 06-29-2004, 05:02 PM
  5. how can 0.00665 not equal 0.00665??!!
    By Susan in forum C++ Programming
    Replies: 10
    Last Post: 02-10-2002, 02:33 AM