Friend function question

For my simple number class;

class Number{
public:
    Number(int num = 0)
    {
        this->num = num;
    }
   
   Number operator+(int i)
  {
  Number temp;
  temp.num = this->num+i;
  return temp;
 }

 friend Number operator+(const int i, const Number& f); //error on this line
 friend ostream& operator<<(ostream& s,const Number& c); //how do i call this?

 void print()
 {
    cout << num << endl;
 }

private:
    int num;
};

Number operator+(const int i, const Number f)
{
  Number temp;
  temp = f.num + i;
  return temp;
}

ostream& operator<<(ostream& s,const Number& c) {
    s <<'(';
    s << c.num;
    s << ')';
    return s;
}

int main() {
    Number a(1);
    Number b(5);
    Number c;

      c = a+5;
      c.print();

      c = 5+a;
      c.print();
         
                c = c<<; //Is this how i call the overload for insertion operator?


    return 0;
}



Ok - my error is on the friend declaration in the class:

C:\Program Files\Common Files\System\Mapi\1033\operator overload.cpp(58) : fatal error C1001: INTERNAL COMPILER ERROR
        (compiler file 'msc1.cpp', line 1786)
         Please choose the Technical Support command on the Visual C++
         Help menu, or open the Technical Support help file for more information
Error executing cl.exe.

What is this? How can i fix?

As well, how do i call the overload for the insertion operator?
LVL 11
bingieAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jaime OlivaresSoftware ArchitectCommented:
The only error I see is the difference between ideclaration and mplementation of operator+
I think must be:

Number operator+(const int i, const Number &f)    // <----- Missing ampersand
{
  Number temp;
  temp = f.num + i;
  return temp;
}

0
SteHCommented:
class Number{
public:
    Number(int num = 0)
    {
        this->num = num;
// here you have circumvented a problem with name collisions
// You should not use the same name as argument and member variable.
// Conventions for member variables are prefixing of "m_" or "f"
// In the following you won't need this pointer anymore.
    }
   
   Number operator+(int i)
  {
  Number temp;
  temp.num = num+i; // remove this->, the member variables are automatically in scope inside member functions.
  return temp;
 }
// but I guess you wanted to increase the value itself. So the body should be
 {
   num+= i;
 }

friend Number operator+(const int i, const Number& f); //error on this line
 friend ostream& operator<<(ostream& s,const Number& c); //how do i call this?
// these two lines were meant to be inside the class definition:

class Number
{
...
 friend Number operator+(const int i, const Number& f); //error on this line
 friend ostream& operator<<(ostream& s,const Number& c); //how do i call this?
};

0
SteHCommented:
You call the line
 friend ostream& operator<<(ostream& s,const Number& c); //how do i call this?
like
cout << c << endl;

I just saw that the friend functions are inside the class declaration. Perhaps try to move the friend declarations at the end of the class definition.
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

SteHCommented:
Beside the comment from jaime_olivares

Number operator+(const int i, const Number f)
{
  Number temp;
  temp.num = f.num + i; // change temp to temp.num here.
  return temp;
}
0
bingieAuthor Commented:
Ok i have those 2 declarations inside the class defination. Here is the new code, still with one errors:

#include <iostream>
using namespace std;

class Number{
public:
    friend Number operator+(const int i, const Number& f); //error on this line
    friend ostream& operator<<(ostream& s,const Number& c);
   
      Number(int num = 0)
    {
        this->num = num;
    }
   
      
      Number operator+(int i)
      {
            Number temp;
            temp.num = num+i;
            return temp;
      }

    void print()
    {
        cout << num << endl;
    }

private:
    int num;
};


ostream& operator<<(ostream& s,const Number& c) {
    s <<'(';
    s << c.num;
    s << ')';
    return s;
}



Number operator+(const int i, const Number& f)
{
      int temp;
      temp = f.num + i;
      return temp;
}




int main() {
    Number a(1);
    Number b(5);
      Number c;

      c = a+5;
      c.print();

      c = 5+a;
      c.print();
      

      cout<<c<<endl;

    return 0;
}


error is:

c:\documents and settings\greg\desktop\c++ final review stuff\operator overload2.cpp(7) : fatal error C1001: INTERNAL COMPILER ERROR
        (compiler file 'msc1.cpp', line 1786)
         Please choose the Technical Support command on the Visual C++
         Help menu, or open the Technical Support help file for more information
Error executing cl.exe.
0
SteHCommented:
Number operator+(const int i, const Number& f)
{
     int temp;
     temp = f.num + i; // still .num missing after temp
     temp.num = f.num + i; // correct
     return temp;
}

And for the operator use:
Number (int iNum = 0)
{
  num = iNum;
}
to have distinct names for member and parameter.

Only the internal compiler error can have many reasons. It might not necessarily one of yours.

Tested the code with Dev-C++ and get
6
6
(6)
Press any key to continue . . .
0
SteHCommented:
Another test with VC++ 6.0 SP5 shows the same result and no compiler errors.

Steps to try are
1) Recreate a fresh command line project and cut and past your code into it.
2) Check service pack and install missing ones.
3) Reinstall VC++
0
itsmeandnobodyelseCommented:
>> (7) : fatal error C1001: INTERNAL COMPILER ERROR

Internal Compiler error C1001 often isn't reproducable at other platforms.

Normally you can try the following to get rid of it:

1. Close your project and delete all temporary project files: *.ncb, *.aps, *.prf, *.plg
2. Open the project again and perform a 'Rebuild All'
3. Rearrange the order of #include statements
4. Remove #include statements that are not absolutely necessary: In header files
    you could use forward declarations if the class contains only pointers or references
    of another class.
5. In header files add a file protection like that for a file named header.h :

    #ifndef HEADER_H    // first line
    #define HEADER_H

    ....

    #endif                    // last line
                                 // add at least one linefeed at end

6. Rename variables used in the line where the error occurs. Try to replace
    'Number' by 'MyNumber'. The problem could be that there is a macro 'Number'
    somewhere.
7. Add a forward declaration of class Number:

    // forward declaration
    class Number;

    class Number
    {
    public:
         ....
    };

8. Implement friend function in the class declaration:

   class Number
   {
   public:
         Number(int i);
         friend Number operator+(int i, const Number& n)
         { return Number(i + n.num); }
   };

9.  Don't use friend if nothing helps:

   class Number
   {
   public:
         Number(int i);
         int getNum() const { return num; }
   };

   inline
   Number operator+(int i, const Number& n)
   { return Number(i + n.getNum()); }
   
10. Don't use 'const int' in the argument list of a function or operator.

     When passing an argument by value it should not made 'const' as it is a safe
     copy that is passed.

Regards, Alex


     

       
0
rstaveleyCommented:
I reproduced your problem with VC 6 and fixed it by putting the following lines before the Number class definition:

--------8<--------
class Number; // Forward reference to Number class
Number operator+(const int i, const Number& f); // Prototype for function about to be declared as a friend
ostream& operator<<(ostream& s,const Number& c); // Prototype for function about to be declared as a friend
--------8<--------

I've been bitten by this one in the past. VC 6 has problems with friends - just like me sometimes - you seem to need to prototype friends before the class definition. VC 7 is altogether much friendlier.
0
itsmeandnobodyelseCommented:
>> VC 6 has problems with friends

Not only with friends. Recently, i had C1001 by the following

#define NUM_MAX double(99999999.99)
#define NUM_MIN double(-99999999.99)

class XYZ
{
     XYZ(double mmin = NUM_MIN, double mmax = NUM_MAX);  // error C1001
}

The problem could be solved by removing the casts to double in the #define statements.

Regards, Alex
0
rstaveleyCommented:
<OFF_TOPIC>

Alex, that one works OK for me on my VC 6 (Version 12.00.8168 - not sure what SP that is)

Here's the test code, I used:
--------8<--------
#include <iostream>

#define NUM_MAX double(99999999.99)
#define NUM_MIN double(-99999999.99)

class XYZ
{
public:
     XYZ(double mmin = NUM_MIN, double mmax = NUM_MAX);  // error C1001
};

XYZ::XYZ(double mmin,double mmax)
{
      std::cout << mmin << ',' << mmax << '\n';
}

int main()
{
      XYZ x;
      XYZ y(10,-10);
}
--------8<--------

The VC 7.1 command line compiler is a free download, though, and the download is well worth the bother if you can't get your employer to pay for VS .NET 2003.

</OFF_TOPIC>
0
itsmeandnobodyelseCommented:
<IN_TOPIC>

>> Alex, that one works OK for me on my VC 6

The issue occured on one new XP machine where VC6 had been automatically installed. The same header file - where the code snippet from above is only a small extract - hadn't changed since years and all other computers - maybe fifty - had no problem to compile. "C1001 internal compiler error" is a very strange error that often isn't reproducable. I suppose it is caused by a multi-threading bug in VC6 and i have a vague suspicion that it occurs more often if  "Precompiled Header Option" was set.

</IN_TOPIC>

Regards, Alex


0
itsmeandnobodyelseCommented:
<OFF_TOPIC>

>> if you can't get your employer to pay for VS .NET 2003

I'm my own employer ;-)  and of course i bought  VS.NET when it was launched here in Europe. I'm working as a consultant and the (big) project i'm working on is a VC6 project that couldn't easily converted to VS.NET (and the VS.NET licenses are a minor issue for the customer).

Do you know, if it is possible to run VC7 compiler in a VS 6.0 environment?

</OFF_TOPIC>

Regards, Alex
0
rstaveleyCommented:
<OFF_TOPIC>

> Do you know, if it is possible to run VC7 compiler in a VS 6.0 environment?

I've not heard of anyone doing this, I'd expect VS's debugger to be too tightly bound to the compiler. Having said that, I vaguely recall someone on EE saying that he used VS with the GNU debugger (gdb) running on a Linux box through I don't know what(!) ... Alas, I can't seem to find any reference to the comment in the EE search facility. I'm going senile.

</OFF_TOPIC>
0
bingieAuthor Commented:
Sorry, back on topic.... :)

Trying to take these two functions one at a time, and neither work. So here is the first with the errors...

#include <iostream >
using namespace std;


class Number{
public:

    friend ostream& operator<<(ostream& s,const Number& c);
   
      Number(int number = 0){number = num;}

private:
    int num;
};


friend ostream& operator<<(ostream& s, Number& c) {
    s <<'(';
    s << c.num;
    s << ')';
    return s;
}


int main() {
    Number a(1);
     
    cout<<a;

    return 0;
}


Errors:

--------------------Configuration: op - Win32 Debug--------------------
Compiling...
Operator Overload Friend Function.cpp
c:\op\operator overload friend function.cpp(17) : error C2255: '<<' : a friend function can only be declared in a class
c:\op\operator overload friend function.cpp(19) : error C2248: 'num' : cannot access private member declared in class 'Number'
        c:\op\operator overload friend function.cpp(13) : see declaration of 'num'
c:\op\operator overload friend function.cpp(21) : error C2562: '<<' : 'void' function returning a value
        c:\op\operator overload friend function.cpp(17) : see declaration of '<<'
Error executing cl.exe.

op.exe - 3 error(s), 0 warning(s)
0
itsmeandnobodyelseCommented:
That compiles:

#include <iostream >
using namespace std;

// forward declarations
class Number;
ostream& operator<<(ostream& s,const Number& c);

class Number
{
public:
   
     Number(int number = 0){number = num;}

private:
    int num;

    friend ostream& operator<<(ostream& s,const Number& c);
};

//  not using friend keyword outside of class declaration
// must be 'const Number&' as in frien declaration
ostream& operator<<(ostream& s, const Number& c)
{
    s <<'(';
    s << c.num;
    s << ')';
    return s;
}


int main() {
    Number a(1);
     
    cout<<a;

    return 0;
}


Seems to be a bug in VC6 compiler

Regards, Alex
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
itsmeandnobodyelseCommented:
>>  Number(int number = 0){number = num;}

That is wrong. You have to change argument and member.


0
bingieAuthor Commented:
Change it to what? Sorry, confused ;)
0
itsmeandnobodyelseCommented:
Number(int number = 0){num = number;}

0
bingieAuthor Commented:
Working Finally, thanks to all!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.