[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Friend function question

Posted on 2004-11-29
20
Medium Priority
?
5,454 Views
Last Modified: 2008-01-09
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?
0
Comment
Question by:bingie
  • 7
  • 5
  • 4
  • +2
20 Comments
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 200 total points
ID: 12696056
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
 
LVL 13

Assisted Solution

by:SteH
SteH earned 200 total points
ID: 12696066
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
 
LVL 13

Expert Comment

by:SteH
ID: 12696132
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 13

Expert Comment

by:SteH
ID: 12696189
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
 
LVL 11

Author Comment

by:bingie
ID: 12696387
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
 
LVL 13

Expert Comment

by:SteH
ID: 12696637
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
 
LVL 13

Expert Comment

by:SteH
ID: 12696679
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
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12698084
>> (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
 
LVL 17

Expert Comment

by:rstaveley
ID: 12700784
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
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12703340
>> 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
 
LVL 17

Expert Comment

by:rstaveley
ID: 12704316
<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
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12706431
<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
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12706526
<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
 
LVL 17

Expert Comment

by:rstaveley
ID: 12706860
<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
 
LVL 11

Author Comment

by:bingie
ID: 12744549
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
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 1600 total points
ID: 12744655
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
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12744661
>>  Number(int number = 0){number = num;}

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


0
 
LVL 11

Author Comment

by:bingie
ID: 12744782
Change it to what? Sorry, confused ;)
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12744960
Number(int number = 0){num = number;}

0
 
LVL 11

Author Comment

by:bingie
ID: 12744985
Working Finally, thanks to all!
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

872 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