Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » friend und non-member function

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
08.09.2006, 21:55 Uhr
mathon



hallo,

ich sollte diese klasse implementieren:


Code:
namespace test_1
{
    class statistician
    {
    public:
        // CONSTRUCTOR
        statistician( );
        // MODIFICATION MEMBER FUNCTIONS
        void next(double r);
        void reset( );
        // CONSTANT MEMBER FUNCTIONS
        int length( ) const;
        double sum( ) const;
        double mean( ) const;
        double minimum( ) const;
        double maximum( ) const;
        // FRIEND FUNCTIONS
        friend statistician operator +
            (const statistician & s1, const statistician & s2);
        friend statistician operator *
            (double scale, const statistician & s);
    private:
        int count;       // How many numbers in the sequence
        double total;    // The sum of all the numbers in the sequence
        double tinyest;  // The smallest number in the sequence
        double largest;  // The largest number in the sequence
    };

    // NON-MEMBER functions for the statistician class
    bool operator ==(const statistician& s1, const statistician& s2);
}


Nur ist mir nicht ganz klar, was der unterschied der friend und non-member function operator == zu den normalen member function in diesem header file ist bzw. wie ich diese im implmentation file dann definieren muss...? :confused:

kann mir hier jemand weiterhelfen?

lg matti

Dieser Post wurde am 08.09.2006 um 22:00 Uhr von mathon editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
08.09.2006, 23:08 Uhr
mischa
Fragender


friend funktionen sind keine member aber sie werden als solche betrachtet. können deshalb auf private elemente zugreifen
non-member funktionen können nur auf public elemente zugreifen
friend und non-member funktionen werden ganz normal implementiert in dem fall

statistician operator *(double scale, const statistician & s)
{/*mach was*/ }
--
Latein Unterricht ist die spätere Rache der Römer an den Germanen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
08.09.2006, 23:37 Uhr
mathon



ah okay, danke! Habe jetzt mal nur den Rumpf testweise implementiert, aber wenn ich dann das testfile (stattest.cpp) ausführe werden ziemlich merkwürdige fehler geworfen:

Also mein header-file

Code:
#ifndef STATS_H     // Prevent duplicate definition
#define STATS_H
#include <iostream>

namespace test_1
{
    class statistician
    {
    public:
        // CONSTRUCTOR
        statistician( );
        // MODIFICATION MEMBER FUNCTIONS
        void next(double r);
        void reset( );
        // CONSTANT MEMBER FUNCTIONS
        int length( ) const;
        double sum( ) const;
        double mean( ) const;
        double minimum( ) const;
        double maximum( ) const;
        // FRIEND FUNCTIONS
        friend statistician operator +
            (const statistician & s1, const statistician & s2);
        friend statistician operator *
            (double scale, const statistician & s);
    private:
        int count;       // How many numbers in the sequence
        double total;    // The sum of all the numbers in the sequence
        double tinyest;  // The smallest number in the sequence
        double largest;  // The largest number in the sequence
    };

    // NON-MEMBER functions for the statistician class
    bool operator ==(const statistician& s1, const statistician& s2);
}

#endif



Hier die Implementation aber nur halt mal der Rumpf, da ich nur mal sehen möchte, ob das testfile überhaupt korrekt startet:

Code:
#include "stats.h"

using namespace test_1;


statistician::statistician()
{

}

void statistician::next(double r)
{
    
}

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

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

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

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

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

bool operator ==(const statistician& s1, const statistician& s2)
{
    return true;
}

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

statistician operator * (double scale, const statistician & s)
{
    return s;
}



Und hier das Testfile:

Code:
#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"


using namespace test_1;
using namespace std;

// PROTOTYPES of functions used in this test program:
void print_menu( );

char get_user_command( );

double get_number( );

void print_values(const statistician& s);

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"
                           << "   MINIMUM      MEAN   MAXIMUM" << endl;
                      cout << "  s1";
                      print_values(s1);
                      cout << "  s2";
                      print_values(s2);
                      cout << "  s3";
                      print_values(s3);
                      break;
            case 'E': if (s1 == s2)
                          cout << "s1 and s2 are equal." << endl;
                      else
                          cout << "s1 and s2 are not equal." << endl;
                      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;
        }
    }
    while ((choice != 'Q'));

    return EXIT_SUCCESS;

}

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 << " E  Test whether s1 == s2" << 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( )
// Library facilties used: iostream.h
{
    char command;

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

double get_number( )
// Library facilties used: iostream.h
{
    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)
// Library facilties used: iostream.h
{
    cout << setw(10) << s.length( );
    cout << setw(10) << s.sum( );
    if (s.length( ) != 0)
    {
        cout << setw(10) << s.minimum( );
        cout << setw(10) << s.mean( );
        cout << setw(10) << s.maximum( );
    }
    else
        cout << "      none      none      none";
    cout << endl;
}



Nur wenn ich dann das testfile ausführe kommen folgende Fehler:


Code:
------ Build started: Project: Assignment1, Configuration: Debug Win32 ------
Compiling...
stattest.cpp
Linking...
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
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
stattest.obj : error LNK2019: unresolved external symbol "bool __cdecl main_savitch_2C::operator==(class main_savitch_2C::statistician const &,class main_savitch_2C::statistician const &)" (??8main_savitch_2C@@YA_NABVstatistician@0@0@Z) referenced in function _main
stattest.obj : error LNK2019: unresolved external symbol "public: void __thiscall main_savitch_2C::statistician::reset(void)" (?reset@statistician@main_savitch_2C@@QAEXXZ) referenced in function _main
C:\Dokumente und Einstellungen\matti\Eigene Dateien\Visual Studio 2005\Projects\Assignment1\Debug\Assignment1.exe : fatal error LNK1120: 4 unresolved externals
Build log was saved at "file://c:\Dokumente und Einstellungen\matti\Eigene Dateien\Visual Studio 2005\Projects\Assignment1\Assignment1\Debug\BuildLog.htm"
Assignment1 - 5 error(s), 0 warning(s)



Weiß hier irgendjemand weiter??

Dieser Post wurde am 09.09.2006 um 00:08 Uhr von mathon editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
08.09.2006, 23:54 Uhr
Spacelord
Hoffnungsloser Fall


Ohne jetzt alles angeschaut zu haben,aber wo holst du denn auf einmal den namespace main_savitch_2C her?

Gruss Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
09.09.2006, 00:09 Uhr
mathon



sorry, der namespace vom testfile heißt natürlich auch test_1, aber das hatte ich nur im posting falsch angeführt, also das kann leider nicht der fehler sein....?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
09.09.2006, 02:04 Uhr
Guybrush Threepwood
Gefürchteter Pirat
(Operator)


 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
09.09.2006, 03:15 Uhr
mathon



das gibts ja nicht, dass ich dieses problem nicht lösen kann, ich sitz da jetzt schon so lange davor, es geht mir einfach nicht ein, woher der kommt...((
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
09.09.2006, 09:07 Uhr
(un)wissender
Niveauwart


Deine freinds sind nicht im globalen namespace.

Wenn im freinds globalen Namensraum bleiben solln...

C++:
//Header
#ifndef STATS_H     // Prevent duplicate definition
#define STATS_H
#include <iostream>

namespace test_1
{
    class statistician;
}

test_1::statistician operator +(const test_1::statistician & s1, const test_1::statistician & s2);
test_1::statistician operator *(double scale, const test_1::statistician & s);
    
namespace test_1
{
    class statistician
    {
    public:
        // CONSTRUCTOR
        statistician( );
        // MODIFICATION MEMBER FUNCTIONS
        void next(double r);
        void reset( );
        // CONSTANT MEMBER FUNCTIONS
        int length( ) const;
        double sum( ) const;
        double mean( ) const;
        double minimum( ) const;
        double maximum( ) const;
        // FRIEND FUNCTIONS
        friend statistician operator+
            (const statistician & s1, const statistician & s2);
        friend statistician operator *
            (double scale, const statistician & s);
    private:
        int count;       // How many numbers in the sequence
        double total;    // The sum of all the numbers in the sequence
        double tinyest;  // The smallest number in the sequence
        double largest;  // The largest number in the sequence
    };

    // NON-MEMBER functions for the statistician class
    bool operator ==(const statistician& s1, const statistician& s2);
}

#endif



Wenn in namespace test_1

C++:
//Header
#ifndef STATS_H     // Prevent duplicate definition
#define STATS_H
#include <iostream>
    
namespace test_1
{
    class statistician;
    statistician operator +(const statistician & s1, const statistician & s2);
    statistician operator *(double scale, const statistician & s);

    class statistician
    {
    public:
        // CONSTRUCTOR
        statistician( );
        // MODIFICATION MEMBER FUNCTIONS
        void next(double r);
        void reset( );
        // CONSTANT MEMBER FUNCTIONS
        int length( ) const;
        double sum( ) const;
        double mean( ) const;
        double minimum( ) const;
        double maximum( ) const;
        // FRIEND FUNCTIONS
        friend statistician operator+
            (const statistician & s1, const statistician & s2);
        friend statistician operator *
            (double scale, const statistician & s);
    private:
        int count;       // How many numbers in the sequence
        double total;    // The sum of all the numbers in the sequence
        double tinyest;  // The smallest number in the sequence
        double largest;  // The largest number in the sequence
    };

    // NON-MEMBER functions for the statistician class
    bool operator ==(const statistician& s1, const statistician& s2);
}

#endif




C++:
//cpp
//...
statistician test_1::operator + (const statistician & s1, const statistician & s2)
{
    return s1;
}

statistician test_1::operator * (double scale, const statistician & s)
{
    return s;
}
//...


--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 09.09.2006 um 09:08 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
09.09.2006, 13:57 Uhr
mathon



Danke erstmals für die Antworten. Ich habe jetzt die ganze Nacht daran gearbeitet, aber es funktioniert noch immer nicht. Die Sache ist die, dass ich das header-file und das test-file so lassen sollte/muss (diese sind aus dem Buch <a href="http://www.cs.colorado.edu/~main/projects/chap02a.html">Data Structures and other objects using C++</a>

HEADER-File - stats.h:

C++:
#ifndef STATS_H // Prevent duplicate definition
#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
int length( ) const;
double sum( ) const;
double mean( ) const;
double minimum( ) const;
double maximum( ) const;
// FRIEND FUNCTIONS
friend statistician operator +
(const statistician & s1, const statistician & s2);
friend statistician operator *
(double scale, const statistician & s);
private:
int count; // How many numbers in the sequence
double total; // The sum of all the numbers in the sequence
double tinyest; // The smallest number in the sequence
double largest; // The largest number in the sequence
};

// NON-MEMBER functions for the statistician class
bool operator ==(const statistician& s1, const statistician& s2);
}

#endif



The IMPLEMENTATION-file namens statsimpl.cpp:

C++:
#include "stats.h"
#include <iostream>


using namespace main_savitch_2C;


statistician::statistician()
{
count = 0;
total = 0;
tinyest = 0;
largest = 0;
}

void statistician::next(double r)
{
total += r;
std::cout << total << std::endl;
}

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

void statistician::reset( )
{
count = 0;
total = 0;
tinyest = 0;
largest = 0;
}

double statistician::sum() const
{
return total;
}

double statistician::mean() const
{
return total/count;
}

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

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

bool operator ==(const statistician& s1, const statistician& s2)
{
    if(s1.length() == s2.length() && s1.mean() == s2.mean() && s1.minimum() == s2.minimum() && s1.maximum() == s2.maximum())
    {
        return true;
    }
    else
        return false;
}

statistician operator + (const statistician & s1, const statistician & s2)
{
statistician s3;

s3.next(s1.sum() + s2.sum());

return s3;
}

statistician operator * (double scale, const statistician & s)
{
return s;
}



und das testfile testimpl.cpp

C++:
#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"

using namespace main_savitch_2C;
using namespace std;

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 << " E Test whether s1 == s2" << 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( )
// Library facilties used: iostream.h
{
char command;

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

return command;
}

double get_number( )
// Library facilties used: iostream.h
{
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)
// Library facilties used: iostream.h
{
cout << setw(10) << s.length( );
cout << setw(10) << s.sum( );
if (s.length( ) != 0)
{
cout << setw(10) << s.minimum( );
cout << setw(10) << s.mean( );
cout << setw(10) << s.maximum( );
}
else
cout << " none none none";
cout << endl;
}

int main(int argc, char* argv[])
{
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 'E': if (s1 == s2)
cout << "s1 and s2 are equal." << endl;
else
cout << "s1 and s2 are not equal." << endl;
break;

case '+': s3 = s1 + s2;
cout << "s3 has been set to s1 + s2" << endl;
break;

case 'T': cout << "The values are given in this table:" << endl;
cout << " LENGTH SUM"
<< " MINIMUM MEAN MAXIMUM" << endl;
cout << " s1";
print_values(s1);
cout << " s2";
print_values(s2);
cout << " s3";
print_values(s3);
break;

case 'Q': cout << "Ridicule is the best test of truth." << endl;
break;
default: cout << choice << " is invalid. Sorry." << endl;
}
}
while ((choice != 'Q'));

return EXIT_SUCCESS;
}



Die beiden Fehler

Code:
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

stattest.obj : error LNK2019: unresolved external symbol "bool __cdecl main_savitch_2C::operator==(class main_savitch_2C::statistician const &,class main_savitch_2C::statistician const &)" (??8main_savitch_2C@@YA_NABVstatistician@0@0@Z) referenced in function _main



werden geworfen wegen des operator+ und operator==. Kannst du mir bitte noch einmal helfen?? - vielleicht bei dir kompilieren oder so...Ich bin wirklich schon verzweifelt...((

matti
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
09.09.2006, 14:11 Uhr
(un)wissender
Niveauwart


Ich hatte die Lösung bereits gepostet. Du musst sie nur anwenden. In der cpp-Datei den namespace vollangeben bei den operatoren.

Das Ganze ist ausschließlich ein namespace Problem. Nimm die mal alle raus, dann gucken ob es geht. Dann nacheinander rein und weiter gucken.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: