operator overloading

Hi,
I have run into a bit of a stand still with some of the build errors i'm receiving for a C++ assignment

The description of the assignment is as follows


Project 1: Fuller FlashDrive

Using FlashDrive.cpp ( .NET or .NET 2010), enhance the FlashDrive class so that it supports the operators +, -, < and >. A sample pile of driver code is shown below to assist you in this effort. Operators + and - should create a new FlashDrive from the two arguments by combining their contents. If you wind up with a FlashDrive with a value stored that exceeds its capacity, print out an error message. If you wind up with a negative capacity or storage value, print out an error message. Operators < and > must return bool and should compare the holdings of the two arguments to determine which one is bigger.

My strong advice is to work one operator at a time, as these steps are very error-prone and lead to many, many compile errors.



My code as as follows

FlashDrive.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#ifndef FLASHDRIVE_H
#define FLASHDRIVE_H


class FlashDrive {
	friend FlashDrive operator+ (FlashDrive used1 , FlashDrive used2);
	friend FlashDrive operator- (FlashDrive used3, FlashDrive used4 );
	
	
	
public:
	
	FlashDrive& operator= (const FlashDrive &usedtotal){

	my_StorageUsed= usedtotal.my_StorageUsed;


	return *this;
	}
	
    FlashDrive( );
	FlashDrive( int capacity, int used, bool pluggedIn );
	

	void plugIn( );
	void pullOut( );
	void writeData( int amount );
	void eraseData( int amount );
	void formatDrive( );

	int  getCapacity( );
	void setCapacity( int amount );
	int  getUsed( );
	void setUsed( int amount );
	bool isPluggedIn( );
private:
	int my_StorageCapacity;   // in kilobytes
	int my_StorageUsed;       // in kilobytes
	bool my_IsPluggedIn;      // am I attached to a computer?
}drive1,drive2;

FlashDrive operator+ (FlashDrive used1, FlashDrive used2 ) {
	
	FlashDrive plus;

	plus = (used1.getUsed()+ used2.getUsed());
	return plus;
}

bool operator< (FlashDrive &lhs,FlashDrive &rhs ) {
   return ( lhs.getUsed() < rhs.getUsed() );
}


bool operator> (FlashDrive &lhs,FlashDrive &rhs ) {
   return ( operator <( rhs, lhs ) );
}

FlashDrive operator- (FlashDrive used3, FlashDrive used4 ){
	FlashDrive minus;
	minus= (used3.getUsed()-used4.getUsed());
	return minus;
}


#endif  


FlashDrive.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "FlashDrive.h"

FlashDrive::FlashDrive( ) {
  my_StorageCapacity = 0;
  my_StorageUsed = 0;
  my_IsPluggedIn = false;
}

FlashDrive::FlashDrive( int capacity, int used, bool pluggedIn ) { 
  my_StorageCapacity = capacity;
  my_StorageUsed = used;
  my_IsPluggedIn = pluggedIn;
}

void FlashDrive::plugIn( ) {
  my_IsPluggedIn = true;
}

void FlashDrive::pullOut( ) {
  my_IsPluggedIn = false;
}

void FlashDrive::writeData( int amount ) {
  my_StorageUsed += amount;
}

void FlashDrive::eraseData( int amount ) {
  my_StorageUsed -= amount;
}

void FlashDrive::formatDrive( ) {
  my_StorageUsed = 0;
}


int  FlashDrive::getCapacity( ) {
  return( my_StorageCapacity );
}

void FlashDrive::setCapacity( int amount ) {
  my_StorageCapacity = amount;
}

int  FlashDrive::getUsed( ) {
  return( my_StorageUsed );
}

void FlashDrive::setUsed( int amount ) {
  my_StorageUsed = amount;
}

bool FlashDrive::isPluggedIn( ) {
  return( my_IsPluggedIn );
}



Main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include "FlashDrive.h"
using namespace std;

void main( )
{
FlashDrive drive1( 10, 0, false );
FlashDrive drive2( 20, 0, false );

drive1.plugIn( );
drive1.formatDrive( );
drive1.writeData( 5 );
drive1.pullOut( );

drive2.plugIn( );
drive2.formatDrive( );
drive2.writeData( 1 );
drive2.pullOut( );

FlashDrive combined = drive1 + drive2;
cout << "this drive's filled to " << combined.getUsed( ) << endl;

FlashDrive other = combined – drive1;
cout << "the other cup's filled to " << other.getUsed( ) << endl;

if (combined > other) {
  cout << "looks like combined is bigger..." << endl;
}
else {
  cout << "looks like other is bigger..." << endl;
}

if (drive2 > other) {
  cout << "looks like drive2 is bigger..." << endl;
}
else {
  cout << "looks like other is bigger..." << endl;
}

if (drive2 < drive1) {
  cout << "looks like drive2 is smaller..." << endl;
}
else {
  cout << "looks like drive1 is smaller..." << endl;
}
}





and the build output errors are as followed



------ Build started: Project: FlashDrive, Configuration: Debug Win32 ------
Build started 7/21/2013 7:02:51 PM.
InitializeBuildStatus:
  Touching "Debug\FlashDrive.unsuccessfulbuild".
ClCompile:
  Main.cpp
c:\documents and settings\administrator\desktop\flashdrive-1\flashdrive.h(46): error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)
          c:\documents and settings\administrator\desktop\flashdrive-1\flashdrive.h(13): could be 'FlashDrive &FlashDrive::operator =(const FlashDrive &)'
          while trying to match the argument list '(FlashDrive, int)'
c:\documents and settings\administrator\desktop\flashdrive-1\flashdrive.h(61): error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)
          c:\documents and settings\administrator\desktop\flashdrive-1\flashdrive.h(13): could be 'FlashDrive &FlashDrive::operator =(const FlashDrive &)'
          while trying to match the argument list '(FlashDrive, int)'
c:\documents and settings\administrator\desktop\flashdrive-1\main.cpp(23): error C2146: syntax error : missing ';' before identifier '–'
c:\documents and settings\administrator\desktop\flashdrive-1\main.cpp(23): error C2065: '–' : undeclared identifier
c:\documents and settings\administrator\desktop\flashdrive-1\main.cpp(23): error C2146: syntax error : missing ';' before identifier 'drive1'
  FlashDrive.cpp
c:\documents and settings\administrator\desktop\flashdrive-1\flashdrive.h(46): error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)
          c:\documents and settings\administrator\desktop\flashdrive-1\flashdrive.h(13): could be 'FlashDrive &FlashDrive::operator =(const FlashDrive &)'
          while trying to match the argument list '(FlashDrive, int)'
c:\documents and settings\administrator\desktop\flashdrive-1\flashdrive.h(61): error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)
          c:\documents and settings\administrator\desktop\flashdrive-1\flashdrive.h(13): could be 'FlashDrive &FlashDrive::operator =(const FlashDrive &)'
          while trying to match the argument list '(FlashDrive, int)'
  Generating Code...

Build FAILED.

Time Elapsed 00:00:00.35
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Last edited on
That is my code from this post

http://www.cplusplus.com/forum/beginner/106915/

I assume you are in the same class with me:)
The errors mean exactly what they say. At various points in your program you have FlashDrive = int expressions, e.g. plus = (used1.getUsed()+ used2.getUsed()); //line 46 .

From your header file, you only have the following possible matching functions:
1
2
3
4
5
6
7
FlashDrive& operator= (const FlashDrive &usedtotal);
//^^^Before this can be called, the compiler has to convert int to FlashDrive,
// which means an implicit call to the constructor  FlashDrive::FlashDrive(int)

//However, you provide no overload to accomplish this
FlashDrive( ); //Obvious why this doesn't work
FlashDrive( int capacity, int used, bool pluggedIn ); //Not enough parameters 


To remedy the issue, you need at least one of the following overloads:
1
2
3
FlashDrive& FlashDrive::operator=(int);

FlashDrive::FlashDrive(int);


Edit:
Or you could call your constructor explicitly, for example:
1
2
//line 46
plus = FlashDrive(0, (used1.getUsed()+ used2.getUsed()), false);


Double Edit:
What am I thinking? You made your operator+ function a friend, so you could do something like:
 
plus.my_StorageUsed = (used1.getUsed()+ used2.getUsed());


This works because as a friend, your function is allowed to access protected and private members.

As you can see, there are multiple ways to tackle this issue.
Last edited on
Great,
This was very insightful, I really appreciate this


I am still getting this weird error that has been following me around since the beginning of the project

FlashDrive.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#ifndef FLASHDRIVE_H
#define FLASHDRIVE_H


class FlashDrive {
	friend FlashDrive operator+ (FlashDrive used1 , FlashDrive used2);
	friend FlashDrive operator- (FlashDrive used3, FlashDrive used4 );
	

public:
	FlashDrive& FlashDrive::operator=(int);
	FlashDrive::FlashDrive(int);
	
	FlashDrive& operator = (const FlashDrive& usedtotal){
		my_StorageUsed= usedtotal.my_StorageUsed;
		return *this;
	}

    FlashDrive( );
	FlashDrive( int capacity, int used, bool pluggedIn );
	

	void plugIn( );
	void pullOut( );
	void writeData( int amount );
	void eraseData( int amount );
	void formatDrive( );

	int  getCapacity( );
	void setCapacity( int amount );
	int  getUsed( );
	void setUsed( int amount );
	bool isPluggedIn( );
private:
	int my_StorageCapacity;   
	int my_StorageUsed;      
	bool my_IsPluggedIn;     
}drive1,drive2;

FlashDrive operator+ (FlashDrive used1, FlashDrive used2 ) {
	
	FlashDrive plus;

	plus.my_StorageUsed = (used1.getUsed()+ used2.getUsed());
	return plus;
}

bool operator< (FlashDrive &lhs,FlashDrive &rhs ) {
   return ( lhs.getUsed() < rhs.getUsed() );
}


bool operator> (FlashDrive &lhs,FlashDrive &rhs ) {
   return ( operator <( rhs, lhs ) );
}

FlashDrive operator - (FlashDrive used3, FlashDrive used4 ){
	FlashDrive minus;
	minus = (used3.getUsed()- used4.getUsed());
	return minus;
}


#endif  


FlashDrive.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "FlashDrive.h"

FlashDrive::FlashDrive( ) {
  my_StorageCapacity = 0;
  my_StorageUsed = 0;
  my_IsPluggedIn = false;
}


FlashDrive::FlashDrive( int capacity, int used, bool pluggedIn ) { 
  my_StorageCapacity = capacity;
  my_StorageUsed = used;
  my_IsPluggedIn = pluggedIn;
}

void FlashDrive::plugIn( ) {
  my_IsPluggedIn = true;
}

void FlashDrive::pullOut( ) {
  my_IsPluggedIn = false;
}

void FlashDrive::writeData( int amount ) {
  my_StorageUsed += amount;
}

void FlashDrive::eraseData( int amount ) {
  my_StorageUsed -= amount;
}

void FlashDrive::formatDrive( ) {
  my_StorageUsed = 0;
}



int  FlashDrive::getCapacity( ) {
  return( my_StorageCapacity );
}

void FlashDrive::setCapacity( int amount ) {
  my_StorageCapacity = amount;
}

int  FlashDrive::getUsed( ) {
  return( my_StorageUsed );
}

void FlashDrive::setUsed( int amount ) {
  my_StorageUsed = amount;
}

bool FlashDrive::isPluggedIn( ) {
  return( my_IsPluggedIn );
}


Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include "FlashDrive.h"
using namespace std;

void main( )
{
FlashDrive drive1( 10, 0, false );
FlashDrive drive2( 20, 0, false );

drive1.plugIn( );
drive1.formatDrive( );
drive1.writeData( 5 );
drive1.pullOut( );

drive2.plugIn( );
drive2.formatDrive( );
drive2.writeData( 1 );
drive2.pullOut( );


FlashDrive combined = drive1 + drive2;
cout << "this drive's filled to " << combined.getUsed( ) << endl;

FlashDrive other = combined – drive1;
cout << "the other cup's filled to " << other.getUsed( ) << endl;

if (combined > other) {
  cout << "looks like combined is bigger..." << endl;
}
else {
  cout << "looks like other is bigger..." << endl;
}

if (drive2 > other) {
  cout << "looks like drive2 is bigger..." << endl;
}
else {
  cout << "looks like other is bigger..." << endl;
}

if (drive2 < drive1) {
  cout << "looks like drive2 is smaller..." << endl;
}
else {
  cout << "looks like drive1 is smaller..." << endl;
}
}




------ Build started: Project: FlashDrive, Configuration: Debug Win32 ------
Build started 7/21/2013 8:39:23 PM.
InitializeBuildStatus:
  Touching "Debug\FlashDrive.unsuccessfulbuild".
ClCompile:
  Main.cpp
c:\documents and settings\administrator\desktop\flashdrive-1\main.cpp(24): error C2146: syntax error : missing ';' before identifier '–'
c:\documents and settings\administrator\desktop\flashdrive-1\main.cpp(24): error C2065: '–' : undeclared identifier
c:\documents and settings\administrator\desktop\flashdrive-1\main.cpp(24): error C2146: syntax error : missing ';' before identifier 'drive1'
  Generating Code...
  Compiling...
  FlashDrive.cpp
  Generating Code...

Build FAILED.

Time Elapsed 00:00:00.42
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========




There are in fact, ;'s in the right places...
Trying to figure out why this keeps occurring?
Last edited on
you're right about the dash having been different...
I verified that
"FlashDrive other = combined - drive1;" is in fact a minus and now I am getting this very strange error

ugh :headache:



------ Build started: Project: FlashDrive, Configuration: Debug Win32 ------
Build started 7/21/2013 8:56:27 PM.
InitializeBuildStatus:
  Touching "Debug\FlashDrive.unsuccessfulbuild".
ClCompile:
  Main.cpp
ManifestResourceCompile:
  All outputs are up-to-date.
Main.obj : error LNK2005: "class FlashDrive __cdecl operator+(class FlashDrive,class FlashDrive)" (??H@YA?AVFlashDrive@@V0@0@Z) already defined in FlashDrive.obj
Main.obj : error LNK2005: "bool __cdecl operator<(class FlashDrive &,class FlashDrive &)" (??M@YA_NAAVFlashDrive@@0@Z) already defined in FlashDrive.obj
Main.obj : error LNK2005: "bool __cdecl operator>(class FlashDrive &,class FlashDrive &)" (??O@YA_NAAVFlashDrive@@0@Z) already defined in FlashDrive.obj
Main.obj : error LNK2005: "class FlashDrive __cdecl operator-(class FlashDrive,class FlashDrive)" (??G@YA?AVFlashDrive@@V0@0@Z) already defined in FlashDrive.obj
Main.obj : error LNK2005: "class FlashDrive drive1" (?drive1@@3VFlashDrive@@A) already defined in FlashDrive.obj
Main.obj : error LNK2005: "class FlashDrive drive2" (?drive2@@3VFlashDrive@@A) already defined in FlashDrive.obj
FlashDrive.obj : error LNK2019: unresolved external symbol "public: class FlashDrive & __thiscall FlashDrive::operator=(int)" (??4FlashDrive@@QAEAAV0@H@Z) referenced in function "class FlashDrive __cdecl operator-(class FlashDrive,class FlashDrive)" (??G@YA?AVFlashDrive@@V0@0@Z)
Main.obj : error LNK2001: unresolved external symbol "public: class FlashDrive & __thiscall FlashDrive::operator=(int)" (??4FlashDrive@@QAEAAV0@H@Z)
Debug\FlashDrive.exe : fatal error LNK1120: 1 unresolved externals

Build FAILED.

Time Elapsed 00:00:00.53
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

now I am getting this very strange error


Not so strange. You defined non-inline functions in a header file that is being included in more than one source file. Therefore, you get non-linline function definitions in more than one source file. This violates the one-definition rule, thus the (linker) errors. Your code generates more than one definition of the same function. Your linker is telling you it doesn't know which one to use.

To correct it, put the implementation in a source file as opposed to the header file, or make the definitions inline in the header file.
Last edited on
I see,

Thanks for pointing that out- I was confused as to how to read those error messages


I think I was able to make the bulk or the errors go away by defining some inline definitions in the header,
but I am still having problems with managing the drive1 and drive2 definitions


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#ifndef FLASHDRIVE_H
#define FLASHDRIVE_H


class FlashDrive {
	friend FlashDrive operator+ (FlashDrive used1 , FlashDrive used2);
	friend FlashDrive operator- (FlashDrive used3, FlashDrive used4 );
	

public:
	FlashDrive& FlashDrive::operator=(int);
	FlashDrive::FlashDrive(int);
	
    FlashDrive& operator = (const FlashDrive& usedtotal){
		my_StorageUsed= usedtotal.my_StorageUsed;
		return *this;
	}

    FlashDrive( );
	FlashDrive( int capacity, int used, bool pluggedIn );
	

	void plugIn( );
	void pullOut( );
	void writeData( int amount );
	void eraseData( int amount );
	void formatDrive( );

	int  getCapacity( );
	void setCapacity( int amount );
	int  getUsed( );
	void setUsed( int amount );
	bool isPluggedIn( );
private:
	int my_StorageCapacity;   // in kilobytes
	int my_StorageUsed;       // in kilobytes
	bool my_IsPluggedIn;      // am I attached to a computer?
}drive1,drive2;

inline FlashDrive operator+ (FlashDrive used1, FlashDrive used2 ) {
	
	FlashDrive plus;

	plus.my_StorageUsed = (used1.getUsed()+ used2.getUsed());
	return plus;
}

inline bool operator< (FlashDrive &lhs,FlashDrive &rhs ) {
   return ( lhs.getUsed() < rhs.getUsed() );
}


inline bool operator> (FlashDrive &lhs,FlashDrive &rhs ) {
   return ( operator <( rhs, lhs ) );
}

inline FlashDrive operator - (FlashDrive used3, FlashDrive used4 ){
	FlashDrive minus;
	minus = (used3.getUsed()- used4.getUsed());
	return minus;
}


#endif  



------ Build started: Project: FlashDrive, Configuration: Debug Win32 ------
Build started 7/21/2013 9:15:22 PM.
InitializeBuildStatus:
  Touching "Debug\FlashDrive.unsuccessfulbuild".
ClCompile:
  Main.cpp
  FlashDrive.cpp
  Generating Code...
ManifestResourceCompile:
  All outputs are up-to-date.
Main.obj : error LNK2005: "class FlashDrive drive1" (?drive1@@3VFlashDrive@@A) already defined in FlashDrive.obj
Main.obj : error LNK2005: "class FlashDrive drive2" (?drive2@@3VFlashDrive@@A) already defined in FlashDrive.obj
Main.obj : error LNK2019: unresolved external symbol "public: class FlashDrive & __thiscall FlashDrive::operator=(int)" (??4FlashDrive@@QAEAAV0@H@Z) referenced in function "class FlashDrive __cdecl operator-(class FlashDrive,class FlashDrive)" (??G@YA?AVFlashDrive@@V0@0@Z)
Debug\FlashDrive.exe : fatal error LNK1120: 1 unresolved externals

Build FAILED.

Time Elapsed 00:00:01.98
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
In the same way you had multiple definitions for the functions, you have multiple definitions for objects drive1 and drive2. One should not define objects in header files.

If you must have them as global objects, the correct way to do it would be to use:

1
2
extern FlashDrive drive1 ;
extern FlashDrive drive2 ;
in the header file after the class definition and:
1
2
FlashDrive drive1 ;
FlashDrive drive2;
in one of the source files, but ideally these would not be global variables.

The other error, the unresolved external symbol, is because you do not define the function named in the error. Provide a definition.
Last edited on
Topic archived. No new replies allowed.