Thread: Friend functions

  1. #1
    Registered User
    Join Date
    Sep 2003
    Posts
    45

    Friend functions

    somebody help me with this...im really confused

    Code:
    #include<iostream.h>
    #include<string.h>
    
    
    class City;
    class Customer
    {
    	friend void displayCustInfo(Customer cust, City city);
    	private:
    		int customerNumber;
    		char zipCode[6];
    	public:
    		Customer(const int=0, const char zip="xxxxx");
    };
    Customer::Customer(const int num, const char zip)
    {
    	customerNumber=num;
    	strcpy(zipCode,zip)
    };
    class City
    {
    	friend void displayCustInfo(Customer cust, City city);
    	private:
    		char name[20];
    		char state[20];
    		char zipCode[6];
    	public:
    		City(const char town='x', const char State='x', const char zip=:"00000");
    };
    City::City(const char town, const char State, const char zip)
    {
    	name=town;
    	state=State;
    	strcpy(zipCode,zip)
    };
    void displayCustInfo(Customer cust, City city)
    {
    	cout<<"Customer #"<<customerNumber<<" lives in "<<name<<", "<<state<<"."<<endl;
    
    void main()
    {
        Customer cust(1572,"60013");
        City city("Cary","Illinois","60013");
        displayCust(aCust,aTown);
    };

  2. #2
    Registered User
    Join Date
    Feb 2002
    Posts
    32
    Perhaps you should tell us what it is you don't understand?

    The friend statement is there to give that function right to access private members of the two classes.

    GL

  3. #3
    Registered User
    Join Date
    Sep 2003
    Posts
    45
    error C2440: 'default argument' : cannot convert from 'char [6]' to 'const char'
    This conversion requires a reinterpret_cast, a C-style cast or function-style cast

    rror C2548: 'Customer::Customer' : missing default parameter for parameter 2

    to start with. i really dont know why all the errors are popping up.

  4. #4
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    What exactly are you confused about? Are you confused about the compile errors? There are lots. Most notably missing semicolons ';', parentheses ')', pointer declarations '*', etc.

    Are you confused about why it wouldn't work if it did compile? It wouldn't work well. You have C-style strings inside your classes which don't copy automatically, but you don't have a user defined copy constructor and operator= to copy them. You have function that takes a copy of these objects instead of a constant reference that would avoid the copy, which isn't wrong but it exposes the copy constructor bug.

    Are you confused about how friends work? A friend function is one that is allowed to access private variables inside a class that normally are hidden to everything outside the class.

    If I could give some more advice (besides the usual get a better book), I would suggest learning smaller pieces at a time. You are probably not ready to learn about friends when you have all these problems with classes and functions and C-style strings. Try and make your program work small pieces at a time. Don't use c-style strings at first, because they are hard. Since you refuse to use the standard C++ libraries, I would suggest sticking to simple types like ints and floats. Put those into your classes and get them working, then move on to strings, and then move on to friends.

    [Edit] Oops, too late. As far as compile errors there are lots and this program is probably too big for you to start trying to fix them now.

  5. #5
    Registered User
    Join Date
    Feb 2002
    Posts
    32
    Edit:
    Better answer above
    Last edited by Hubas; 10-29-2003 at 08:08 PM.

  6. #6
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    const char zip="xxxxx"

    Here you are trying to convert from a string of 6 char (5 x's and a terminating null char) to a single const char. this won't work, and I suspect it is the source of the first compiler error. Since it won't work, you don't have a default arguement for the second parameter of the constructor, which leads to the second error. Fix the first one and the second will probably disappear. This is a common theme in error correction.

    The second problem here is that I'm not familiar with the syntax for declaring a default value for C style string arguments. I'll have to do some research on that.

    BTW you repeat the attempts to change strings into to single char several times during the program, and at one point you try to do the reverse, which is also an error.

  7. #7
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    Code:
    MyClass(const int thisint, const char* thattext = 0)
              :myInt(thisint)
    {
      strcpy(myText, thattext);
    }
    Okay, here's an example of an inlined class constructor using a default C style string as the second parameter with the default value of 0 (ie NULL, empty string, whatever you want to call it). If the constructor receives a C style string as the second parameter, then it is copied into a data variable called myText using strycpy(), otherwise myText will be empty/NULL/0/whatever, too, as a result of copying the default value for thatText into myText.
    Last edited by elad; 10-30-2003 at 12:01 PM.

  8. #8
    Registered User
    Join Date
    Sep 2003
    Posts
    45
    ok, well i sat down to actually look over the code and with the help of the book and you guys, i got it down to just saying that the variables in the declaration of the displayCustInfo function are undefineable, but i can fix that myself im sure. thanks again guys.

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Friends friends friends. I cannot stand the friend keyword. It is usually used to override the inherent protection mechanisms of C++ which to me....if you use it....why are you coding in C++.

    A better usage would be to create a function that allows your class to display its own information. The method is up to you. If you want to use a non-class function to display the info then pass a class pointer to the function.


    All you are doing is overriding some very important mechanisms. displayCust() should not be able to display info about things it has no business knowing about. A better use would be:

    Customer cust(<info>);
    cust->Display();
    City newcity(<info>);
    newcity->Display();

    or create a display class and use it to show the information contained in the classes.

    or
    Code:
    class BaseClass
    {
       public:
         ...
         virtual void Display();
    };
    
    class Derived:public BaseClass
    {
       public:
       ...
       virtual void Display();
    };
    In this way the display is a functional part of each class and not just sitting out there willy nilly. Each class knows how to display its own info and can be re-defined as well if more display options are required.

    No need for friend here because the compiler will automatically call the correct display function based on the class calling it.
    Last edited by VirtualAce; 10-30-2003 at 11:05 PM.

  10. #10
    Registered User
    Join Date
    Sep 2003
    Posts
    45
    heres a new program im workin on... what needs to be done to fix these errors?

    error C2027: use of undefined type 'Veterinarian'
    see declaration of 'Veterinarian'
    error C2228: left of '.veterinarianName' must have class/struct/union type
    error C2511: 'setValues' : overloaded member function 'void (char,char,char)' not found in 'Veterinarian'
    see declaration of 'Veterinarian'
    error C2512: 'Veterinarian' : no appropriate default constructor available
    Error executing cl.exe.




    Code:
    #include<iostream.h>
    #include<string.h>
    
    class Veterinarian;
    class Pet
    {
    	
    	private:
    		char petName[10];
    		char ownerName[10];
    		int petAge;
    		char petBreed[30];
    		char veterinarianName[10];
    	public:
    		friend void displayValues(Veterinarian vet);
    		void setValues(char petname[10], char owner[10], int age, char breed[10], char vetName[10]);
    		void displayValues(Veterinarian vet);
    };
    
    void Pet::setValues(char petname[10], char owner[10], int age, char breed[10], char vetName[10])
    {
    	strcpy(petName,petname);
    	strcpy(ownerName,owner);
    	petAge=age;
    	strcpy(petBreed,breed);
    	strcpy(veterinarianName,vetName);
    };
    void Pet::displayValues(Veterinarian vet)
    {
        if(strcmp(veterinarianName,vet.veterinarianName)==0)
           cout<<petName<<" owned by "<<ownerName<<" seen by Dr. "<<veterinarianName<<endl;
    };
    class Veterinarian
    {
    	
    	private:
    		char veterinarianName[10];
    		char address[20];
    		char phoneNumber[9];
    	public:
    		Veterinarian(char veterinarianName, char address, char phoneNumber);
    		friend void displayValues(Veterinarian vet);
    		void setValues(char vetName[10], char Add[20], char phone[9]);
    };
    void Veterinarian::setValues(char vetname, char Add, char phone)
    {
    	strcpy(veterinarianName, vetname);
    	strcpy(address, Add);
    	strcpy(phoneNumber,phone);
    };
    int main()
    {
        int x;
        Pet pets[10];
        Veterinarian vet;
        pets[0].setValues("Murphy","Andrea",13,"Labrador","Souri");
        pets[1].setValues("Socks","Audrey",7,"Domestic Cat","Souri");
        pets[2].setValues("Squawk","Natalie",45,"Parrot","Davis");
        pets[3].setValues("Marley","Chris",4,"Labrador","Unger");
        pets[4].setValues("Snip","Mike",3,"Lizzard","Davis");
        pets[5].setValues("Karma","Joyce",3,"Domestic Cat","Souri");
        pets[6].setValues("Eloise","Colleen",10,"Schnauzer","O'Shea");
        pets[7].setValues("Hagen","Annette",7,"Beagle","Unger");
        pets[8].setValues("Missy","Linda",6,"American Staffordshire","Davis");
        pets[9].setValues("Autumn","Geoff",4,"Irish Setter","Souri");
        vet.setValues("Souri","200 Bloomigdale Rd.","289-4400");
        for(x = 0; x<10; ++x)
          pets[x].displayValues(vet);
    }
    Last edited by ForlornOdium; 11-02-2003 at 09:27 PM.

  11. #11
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Firstly, you only need a semi-colon (;) after the curly braces of a struct, class, or union, not of functions, control structures, etc. Strictly speaking, thats not an error though... just something you don't need.

    Secondly, you can use a pointer or reference of a class before giving it a full declaration (i.e. with only a forward declaration). SO the line
    Code:
    friend void displayValues(Veterinarian vet);
    is problematic in this respect. You are trying to use Veterinarian (not a pointer or reference, but the type itself) before the full declaration.

    Thirdly, here,
    Code:
    cout<<petName<<" owned by "<<ownerName<<" seen by Dr. "<<veterinarianName<<endl;
    veterinarianName has no context... only from within Veterinarian or a friend class/function (attached to the appropriate object) since it is private data. Pet has no access to it.

    Fourthly, look closely at your declaration and definition of setValues for Veterinarian. In particular, look at the parameters.

    Fifthly, you try to create 'vet' with the default Veterinarian constructor, but you provide no such constructor (and since you did provide a constructor your compiler decided not to provide it for you).

    Most of these errors you really should be able to find if you look a little for them. They are rather self-explanatory.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  12. #12
    Registered User
    Join Date
    Sep 2003
    Posts
    45
    does anybody know why in my display values function, it says that anything that has to do with the veterinarian class is an undefined type of Veterinarian. my friend, who thinks he knows what he's doing said he doesn't know either.

    Code:
    #include<iostream.h>
    #include<string.h>
    
    class Veterinarian;
    class Pet
    {
    	
    	private:
    		char petName[10];
    		char ownerName[10];
    		int petAge;
    		char petBreed[30];
    		char veterinarianName[10];
    	public:
    		friend void displayValues(Veterinarian vet);
    		void setValues(char petname[10], char owner[10], int age, char breed[10], char vetName[10]);
    		void displayValues(Veterinarian vet);
    };
    
    void Pet::setValues(char petname[10], char owner[10], int age, char breed[10], char vetName[10])
    {
    	strcpy(petName,petname);
    	strcpy(ownerName,owner);
    	petAge=age;
    	strcpy(petBreed,breed);
    	strcpy(veterinarianName,vetName);
    };
    void Pet::displayValues(Veterinarian vet)
    {
        if(strcmp(vet.veterinarianName, vet.veterinarianName)==0)
           cout<<petName<<" owned by "<<ownerName<<" seen by Dr. "<<veterinarianName<<endl;
    };
    class Veterinarian
    {
    	
    	private:
    		char veterinarianName[10];
    		char address[20];
    		char phoneNumber[9];
    	public:
    		friend void displayValues(Veterinarian vet);
    		void setValues(char vetName[10], char Add[20], char phone[9]);
    };
    void Veterinarian::setValues(char vetname[10], char Add[20], char phone[9])
    {
    	strcpy(veterinarianName, vetname);
    	strcpy(address, Add);
    	strcpy(phoneNumber,phone);
    };
    void main()
    {
        int x;
        Pet pets[10];
        Veterinarian vet;
        pets[0].setValues("Murphy","Andrea",13,"Labrador","Souri");
        pets[1].setValues("Socks","Audrey",7,"Domestic Cat","Souri");
        pets[2].setValues("Squawk","Natalie",45,"Parrot","Davis");
        pets[3].setValues("Marley","Chris",4,"Labrador","Unger");
        pets[4].setValues("Snip","Mike",3,"Lizzard","Davis");
        pets[5].setValues("Karma","Joyce",3,"Domestic Cat","Souri");
        pets[6].setValues("Eloise","Colleen",10,"Schnauzer","O'Shea");
        pets[7].setValues("Hagen","Annette",7,"Beagle","Unger");
        pets[8].setValues("Missy","Linda",6,"American Staffordshire","Davis");
        pets[9].setValues("Autumn","Geoff",4,"Irish Setter","Souri");
        vet.setValues("Souri","200 Bloomigdale Rd.","289-4400");
        for(x = 0; x<10; ++x)
          pets[x].displayValues(vet);
    }

  13. #13
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Before you call anything from Veterinarian, you need to provide a full declaration (not just a forward declaration). The code trying to access the class must know about the class (what its methods and their signatures are, etc.)

    For example:
    Code:
    // A bad example:
    class A;
    
    void foo(const A& obj1) // Okay... A forward declaration is all that is needed for a pointer or reference
    {
      A obj2; // Not okay... Cannot instantiate a type with no declaration
      obj1.bar( ); // Not okay... There is no full declaration of A
    }
    
    class A
    {
    public:
      void bar( );
    };
    
    void A::bar( )
    {
      // ...
    }
    
    // ...
    // And now, a good example.
    
    class A
    {
      void bar( );
    };
    
    void foo(const A& obj1)
    {
      obj1.bar( );
    }
    
    void A::bar( )
    {
      // ...
    }
    There are a couple other problems with that function. See the previous post for those.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  14. #14
    Registered User
    Join Date
    Sep 2003
    Posts
    45
    i can't get this to read right! eitehr i have a problem with the objects in the pet class..or the ones in the veterinarian class.

    Code:
    void Pet::displayValues(Veterinarian vet)
    {
        if(strcmp(vet.veterinarianName, vet.veterinarianName)==0)
           cout<<petName<<" owned by "<<ownerName<<" seen by Dr. "<<veterinarianName<<endl;
    };

  15. #15
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Here's some hints:

    What does 'veterinarianName' beling to?
    What is the access level of 'veterinarianName'?
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Friend Functions
    By rculley1970 in forum C++ Programming
    Replies: 5
    Last Post: 03-25-2007, 03:25 AM
  2. Static member functions more efficient?
    By drrngrvy in forum C++ Programming
    Replies: 6
    Last Post: 06-16-2006, 07:07 AM
  3. Friend template functions
    By lyx in forum C++ Programming
    Replies: 4
    Last Post: 10-02-2003, 01:11 PM
  4. inline friend functions.
    By sean in forum C++ Programming
    Replies: 2
    Last Post: 01-03-2002, 12:37 PM
  5. Visual C++ and friend functions giving errors
    By Unregistered in forum C++ Programming
    Replies: 4
    Last Post: 11-04-2001, 06:55 PM