Help with linking error (overloaded operator on friend function)

I was trying to follow a homework example I found online and am getting stuck.

I haven't done much with over loaded operators, friend functions, or reference operators, so am having a hard time figuring out why I get a linking error.

They give you the header file with the function prototypes defined (I'm assuming this is correct since it was given as part of the problem):

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
#ifndef STATS_H   
#define STATS_H
#include <iostream>
namespace main_savitch_2C
{
    class statistician
    {
    public:
        // CONSTRUCTOR
        statistician( );
        // MODIFICATION MEMBER FUNCTIONS
        void next(double r);
        void reset( );
        // CONSTANT MEMBER FUNCTIONS
        double abs_maximum( ) const;
        double abs_minimum( ) const;
        int length( ) const;
        double maximum( ) const;
        double mean( ) const;
        double minimum( ) const;
        double recent( ) const;
        double sum( ) const;
        // FRIEND FUNCTIONS
        friend statistician operator +
            (const statistician& s1, const statistician& s2);
        friend statistician operator *
            (double x, const statistician& s1);
    private:
	double my_abs_maximum; 
	double my_abs_minimum; 
        int my_length;         
        double my_maximum;     
        double my_minimum;     
	double my_recent;      
        double my_sum;         
    };
}

#endif 


Then give you a way to test the code that you write:

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <cctype>    // Provides toupper
#include <iomanip>   // Provides setw to set the width of an output
#include <iostream>  // Provides cout, cin
#include <cstdlib>   // Provides EXIT_SUCCESS
#include "stats.h"   // Provides the Statistician class
using namespace main_savitch_2C;
using namespace std;

void print_menu( );


char get_user_command( );

double get_number( );

void print_values(const statistician& s);

void print_menu( )
{
    cout << endl;
    cout << "The following choices are available: " << endl;
    cout << " R  Activate one of the reset( ) functions" << endl;
    cout << " 1  Add a new number to the 1st statistician s1" << endl;
    cout << " 2  Add a new number to the 2nd statistician s2" << endl;
    cout << " 3  Add a new number to the 3rd statistician s3" << endl;
    cout << " T  Print a table of values from the statisticians" << endl;
    cout << " +  Set the third statistician s3 equal to s1 + s2" << endl;
    cout << " *  Set the third statistician s3 equal to x*s1" << endl;
    cout << " Q  Quit this test program" << endl;
}

char get_user_command( )

{
    char command;

    cout << "Enter choice: ";
    cin >> command; 
   
    return command;
}

double get_number( )

{
    double result;

    cout << "Please enter the next real number for the sequence: ";
    cin  >> result;
    cout << result << " has been read." << endl;
    return result;
}

void print_values(const statistician& s)

{
    cout << setw(10) << s.length( );
    cout << setw(10) << s.sum( );
    if (s.length( ) != 0)
    {
        cout << setw(10) << s.abs_minimum( );
        cout << setw(10) << s.abs_maximum( );
        cout << setw(10) << s.minimum( );
        cout << setw(10) << s.mean( );
        cout << setw(10) << s.maximum( );
    }
    else
        cout << "      none      none      none      none      none";
    cout << endl;
}

int main( )
{
    statistician s1, s2, s3;  // Three statisticians for us to play with
    char choice;              // A command character entered by the user
    double x;                 // Value for multiplication x*s1

    cout << "Three statisticians s1, s2, and s3 are ready to test." << endl;

    do
    {
        cout << endl;
        print_menu( );
        choice = toupper(get_user_command( ));
        switch (choice)
        {
	case 'R':
	    cout << "Which one should I reset (1, 2, 3) " << endl;
	    choice = get_user_command( );
	    switch (choice)
	    {
	    case '1': s1.reset( );
		break;
	    case '2': s2.reset( );
		break;
	    case '3': s3.reset( );
		break;
	    }
	    cout << "Reset activated for s" << choice << "." << endl;
	    break;
	case '1':
	    s1.next(get_number( ));
	    break;
	case '2':
	    s2.next(get_number( ));
	    break;
	case '3':
	    s3.next(get_number( ));
	    break;
	case 'T':
	    cout << "The values are given in this table:" << endl;
	    cout << "        LENGTH       SUM"
		 << "   ABS_MIN   ABS_MAX"
		 << "   MINIMUM      MEAN   MAXIMUM" << endl;
	    cout << "  s1";
	    print_values(s1);
	    cout << "  s2";
	    print_values(s2);
	    cout << "  s3";
	    print_values(s3);
	    break;
	case '+':
	    s3 = s1 + s2;
	    cout << "s3 has been set to s1 + s2" << endl;
	    break;
	case '*':
	    cout << "Please type a value for x: ";
	    cin >> x;
	    s3 = x * s1;
	    cout << "s3 has been set to " << x << " * s1" << endl;
	    break;
	case 'Q':
	    cout << "Ridicule is the best test of truth." << endl;
	    break;
	default:
	    cout << choice << " is invalid. Sorry." << endl;
	    break;
        }
    }
    while (choice != 'Q');

    return EXIT_SUCCESS;

}


So I wrote the following with stub functions, but get unresolved external symbol for the + OPERATOR and * OPERATOR in the MAIN function of the test code.

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
67
68
69
70
71
72
73
74
#include <cstdlib>
#include <assert.h>
#include "stats.h"

using namespace main_savitch_2C;
using namespace std;

statistician::statistician()
{

}

void statistician::next(double r)
{

}

void statistician::reset()
{

}

double statistician::abs_maximum() const
{
  return 0;
}

double statistician::abs_minimum() const
{
  return 0;
}

int statistician::length() const
{
  return 0;
}

double statistician::maximum() const
{
  return 0;
}

double statistician::mean() const
{
  return 0;
}

double statistician::minimum() const
{
  return 0;
}

double statistician::recent() const
{
  return 0;
}

double statistician::sum() const

{
  return 0;
}

const statistician operator +(const statistician& s1, const statistician& s2)
{
  statistician answer;
  return answer;
}

statistician operator *(double x, const statistician& s1)
{
  statistician answer;
  return answer;
}


Why do i get those errors? Help would greatly be appreciated, as well as an explanation. I've read the articles I could find on this site and have searched the web, but I still don't understand the problem.

actual errors:
1>------ Build started: Project: Statistician, Configuration: Debug Win32 ------
1>  stats.cpp
1>stattest.obj : error LNK2019: unresolved external symbol "class main_savitch_2C::statistician __cdecl main_savitch_2C::operator*(double,class main_savitch_2C::statistician const &)" (??Dmain_savitch_2C@@YA?AVstatistician@0@NABV10@@Z) referenced in function _main
1>stattest.obj : error LNK2019: unresolved external symbol "class main_savitch_2C::statistician __cdecl main_savitch_2C::operator+(class main_savitch_2C::statistician const &,class main_savitch_2C::statistician const &)" (??Hmain_savitch_2C@@YA?AVstatistician@0@ABV10@0@Z) referenced in function _main


Thanks!
The error clearly states how the operators are supposed look like:

1
2
3
4
5
6
7
8
9
10
11
const statistician main_savitch_2C::operator +(const statistician& s1, const statistician& s2)
{
  statistician answer;
  return answer;
}

statistician main_savitch_2C::operator *(double x, const statistician& s1)
{
  statistician answer;
  return answer;
}


'using namespace' is not a good idea. Why that effort with creating a namespace and then later wipe it out?
And like you see the compiler do not always get it the way you think.
Thanks for the help,

However, I'm still not able to resolve the issue.

When I make the modifications to take the 'using namespace' out of my file I then get the error:

'statistician' does not name a type


I've gone back and reread the namespace tutorial on this site but still can't figure out what I'm doing wrong.

Since 'statistician' is also part of the namespace 'main_savitch_2C' you have to prepend it as well when you're outside that namespace.
Topic archived. No new replies allowed.