C++ friend function

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Der Andere

    C++ friend function

    I've got a problem concerning the << operator. Although I've declared it as
    a friend function it cannot access the private member of the class AVLtree.
    Some code:

    ------------------
    class AVLtree
    {
    public:
    friend ostream& operator << (ostream& os, AVLtree& t){};
    .... some unimportant stuff ...
    private:
    Tree tree;
    };

    ostream& operator << (ostream& os, AVLtree& t)
    {
    // if (t.tree!=NULL)
    os << *(t.tree);
    return os;
    }
    ----------------

    I cannot figure out why the compiler tells

    error C2248: 'tree' : cannot access private member declared in class
    'AVLtree'

    Any advice?

    Thanks in advance,
    Matthias

    --
    Für emails Anweisung in der Adresse befolgen


  • Kevin Goodsell

    #2
    Re: C++ friend function

    Der Andere wrote:
    [color=blue]
    > I've got a problem concerning the << operator. Although I've declared it as
    > a friend function it cannot access the private member of the class AVLtree.
    > Some code:[/color]

    When posting code, please try to make it compilable. This is FAQ 5.8.
    [color=blue]
    >
    > ------------------
    > class AVLtree
    > {
    > public:
    > friend ostream& operator << (ostream& os, AVLtree& t){};[/color]

    What's with the '{}'? I don't even know if that's legal, and it
    certainly seems nonsensical. Are you defining the function here, or are
    you defining it later?
    [color=blue]
    > ... some unimportant stuff ...
    > private:
    > Tree tree;
    > };
    >
    > ostream& operator << (ostream& os, AVLtree& t)
    > {
    > // if (t.tree!=NULL)
    > os << *(t.tree);
    > return os;
    > }[/color]

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.

    Comment

    • Buster

      #3
      Re: C++ friend function

      Der Andere wrote:
      [color=blue]
      > I've got a problem concerning the << operator. Although I've declared it as
      > a friend function it cannot access the private member of the class AVLtree.
      > Some code:
      >
      > ------------------
      > class AVLtree
      > {
      > public:
      > friend ostream& operator << (ostream& os, AVLtree& t){};[/color]

      Defined here.
      [color=blue]
      > ... some unimportant stuff ...
      > private:
      > Tree tree;
      > };
      >
      > ostream& operator << (ostream& os, AVLtree& t)
      > {
      > // if (t.tree!=NULL)
      > os << *(t.tree);
      > return os;
      > }[/color]

      And here.
      [color=blue]
      > ----------------
      >
      > I cannot figure out why the compiler tells
      >
      > error C2248: 'tree' : cannot access private member declared in class
      > 'AVLtree'[/color]

      Funny, mine says
      "error: redefinition of `std::ostream& operator<<(std: :ostream&, AVLtree&)".
      [color=blue]
      > Any advice?[/color]

      Post the real code.

      --
      Regards,
      Buster.

      Comment

      • Der Andere

        #4
        Re: C++ friend function

        Ok then, underneath you'll find the complete code, as I got it. It should
        compile now.

        Regards,
        Matthias

        ----------------------

        #include <iostream>
        #include <cassert>
        #include <iomanip>

        using namespace std;

        typedef int T;

        T max(T a, T b)
        {
        return a > b ? a : b ;
        }

        T min(T a, T b)
        {
        return a < b ? a : b ;
        }

        // ----------

        enum Child {Left=0, Right=1};

        Child opposite(Child k)
        {
        return Child(1-k);
        }

        // ----------

        enum Balance { LeftBal=-1, Balanced=0, RightBal=1};

        const bool deeper = true;
        const bool sameDepth = false;

        // ----------

        typedef class Node* Tree;
        const Tree Empty = NULL;

        class Node
        {
        enum { Arity=2 };
        Tree children[Arity];
        int b;
        T e;
        public:
        Node(T & v) : e(v), b(0) { for (int i=0;i<Arity;i+= 1) children[i]=Empty; }
        ~Node();

        friend int& bal(Tree p);
        friend T& el (Tree p);
        friend Tree & child(Tree p, Child k);
        };

        int& bal(Tree p) { assert(p); return p->b; }

        T& el (Tree p) { assert(p); return p->e; }

        Tree& child(Tree p, Child k) { assert(p); return p->children[k]; }

        Tree& left(Tree p) { return child(p,Left); }

        Tree& right(Tree p) { return child(p,Right); }

        Node :: ~Node()
        {
        for (int i=0;i<Arity;i+= 1)
        if (children[i])
        delete children[i];
        }

        // ----------

        void rotate (Tree & root, Child c)
        {
        Child other = opposite(c);
        assert(child(ro ot,other)); // other Child should exist
        Tree oldRoot = root;

        root = child(root,othe r);
        child(oldRoot,o ther) = child(root,c);
        child(root,c) = oldRoot;

        if (c==Left)
        {
        bal(oldRoot) -= 1+ max(bal(root),0 );
        bal(root) -= 1- min(bal(oldRoot ),0);
        }
        else
        {
        bal(oldRoot) += 1- min(bal(root),0 );
        bal(root) += 1+ max(bal(oldRoot ),0);
        }
        }

        void rotateDubbel (Tree & root, Child c)
        {
        Child other = opposite(c);
        rotate(child(ro ot,other),other );
        rotate(root,c);
        }

        // ----------

        bool insertRight(Tre e& tree, T v);
        bool insertLeft(Tree & tree, T v);

        bool insert(Tree& tree, T v) // returns true if tree becomes deeper
        {
        if (tree==Empty)
        {
        tree = new Node (v);
        return deeper;
        }
        else if (v==el(tree))
        return sameDepth;
        else if (v<el(tree))
        return insertLeft (tree,v);
        else
        return insertRight (tree,v);
        }

        bool insertRight(Tre e& tree, T v)
        {
        if (insert(right(t ree),v))
        {
        bal(tree) += 1;
        switch(bal(tree ))
        {
        case 2:
        if (bal(right(tree )) == LeftBal)
        rotateDubbel(tr ee,Left);
        else
        rotate(tree,Lef t);
        return sameDepth;
        case 1: return deeper;
        case 0: return sameDepth;
        default: assert(false);
        }
        }
        else
        return sameDepth;
        }

        bool insertLeft(Tree & tree, T v)
        {
        if (insert(left(tr ee),v))
        {
        bal(tree) -= 1;
        switch(bal(tree ))
        {
        case -2:
        if (bal(left(tree) ) == RightBal)
        rotateDubbel(tr ee,Right);
        else
        rotate(tree,Rig ht);
        return sameDepth;
        case -1: return deeper;
        case 0: return sameDepth;
        default: assert(false);
        }
        }
        else
        return sameDepth;
        }

        bool contains (Tree tree, T v)
        {
        if (tree == Empty)
        return false;
        else if (el(tree) == v)
        return true;
        else if (el(tree) < v)
        return contains(right( tree),v);
        else
        return contains(left(t ree),v);
        }

        bool sorted (Tree tree, T* v=NULL)
        {
        if (tree==Empty)
        return true;
        else
        {
        bool sl = sorted(left(tre e),v);
        if (v && el(tree) <= *v)
        {
        sl = false;
        cout << "element " << *v << " staat op de verkeerde plaats\n";
        }
        v = &(el(tree));
        return sorted(right(tr ee),v) && sl;
        }
        }

        bool balanced (Tree tree, int& d)
        {
        if (tree==Empty)
        {
        d = 0;
        return true;
        }
        else
        {
        int l=0, r=0;
        bool bl = balanced(left(t ree),l);
        bool br = balanced(right( tree),r);
        if (bal(tree) != r-l)
        cout << "balansfact or in knoop met " << el(tree) << " verkeerd\n";
        if (abs(r-l)>1)
        cout << "avl tree is op knoop met " << el(tree) << " uit balans\n";
        d = max(l,r) + 1;
        return bl && br && bal(tree) == r-l && abs(r-l)<=1;
        }
        }


        ostream& operator << (ostream& os, Node& n)
        {
        static int indent = 0;
        const int stap = 3;
        indent += stap;
        if (right(&n)!=Emp ty)
        os << *right(&n);
        os << setw(indent-stap) << "" << el(&n) << " bal=" << bal(&n) << endl;
        if (left(&n)!=Empt y)
        os << *left(&n);
        indent -= stap;
        return os;
        }

        // ----------
        // ----------

        class AVLtree
        {
        Tree tree;
        public:
        AVLtree(): tree(Empty) {}
        ~AVLtree() { if (tree) delete tree; }
        friend ostream& operator << (ostream& os, AVLtree& t);
        void Insert(T v) { insert(tree,v); }
        bool Contains(T v) { return contains(tree,v ); }
        bool Sorted() { return sorted(tree); }
        bool Balanced() {int d =0; return balanced(tree,d ); }
        };

        ostream& operator << (ostream& os, AVLtree& t)
        {
        if (t.tree!=Empty)
        os << *(t.tree);
        return os;
        }


        // ----------

        void main ()
        {
        // int val = 2;
        // Node<int>* ptr = new Node<int>(val);
        // cout << *ptr ;

        /* Node<int>* t = Empty;
        int rij[10] = {0,9,1,2,3,4,5, 6,7,8};
        for (int i = 0;i<10;i+=1)
        {
        insert(t,rij[i]);
        cout << *t << endl;
        }
        */

        AVLtree t;
        // int rij[10] = {0,9,1,2,4,4,5, 6,7,8};
        // int rij[10] = {5,3,7,2,4,6,1, 1,1,1};
        int rij[10] = {4,2,6,1,3,5,7, 1,1,1};
        for (int i = 0;i<10;i+=1)
        {
        t.Insert(rij[i]);
        cout << t << endl;
        if (!t.Sorted() || !t.Balanced())
        cout << "Improper AVL tree\n";
        }
        for (int j = -1;j<11;j+=1)
        cout << "contains " << j << " = " << boolalpha << t.Contains(j) << endl;


        }


        Comment

        • Buster

          #5
          Re: C++ friend function

          Der Andere wrote:[color=blue]
          > Ok then, underneath you'll find the complete code, as I got it. It should
          > compile now.[/color]

          No, I get "error: `main' must return `int'".

          Having fixed that, yes, it does compile. So, what, you fixed it?
          What happened to "error C2248: 'tree' : cannot access private member
          declared in class 'AVLtree'"?

          --
          Regards,
          Buster.

          Comment

          • Der Andere

            #6
            Re: C++ friend function

            > Der Andere wrote:[color=blue][color=green]
            > > Ok then, underneath you'll find the complete code, as I got it. It[/color][/color]
            should[color=blue][color=green]
            > > compile now.[/color]
            >
            > No, I get "error: `main' must return `int'".
            >
            > Having fixed that, yes, it does compile. So, what, you fixed it?
            > What happened to "error C2248: 'tree' : cannot access private member
            > declared in class 'AVLtree'"?[/color]

            Errh, no, I didn't fix it. I've still got it.
            I've never had this kind of problem with my compiler.
            But if it works on your computer, the fault may be in my system, not in the
            code?!

            Regards,
            Matthias


            Comment

            • Buster

              #7
              Re: C++ friend function

              Der Andere wrote:
              [color=blue]
              > Errh, no, I didn't fix it. I've still got it.
              > I've never had this kind of problem with my compiler.
              > But if it works on your computer, the fault may be in my system, not in the
              > code?![/color]

              What compiler is it, and what version? I gather that with Visual C++,
              anything before 7.1 was pretty crappy. If I see any problems with the
              code you posted I'll let you know.

              --
              Regards,
              Buster.

              Comment

              • Der Andere

                #8
                Re: C++ friend function

                > > Errh, no, I didn't fix it. I've still got it.[color=blue][color=green]
                > > I've never had this kind of problem with my compiler.
                > > But if it works on your computer, the fault may be in my system, not in[/color][/color]
                the[color=blue][color=green]
                > > code?![/color]
                >
                > What compiler is it, and what version? I gather that with Visual C++,
                > anything before 7.1 was pretty crappy.[/color]

                Oh, I've got Visual C++ 6.0. So maybe Microsoft is the problem, not me ;-)
                [color=blue]
                >If I see any problems with the
                > code you posted I'll let you know.[/color]

                Thanks!

                Regards,
                Matthias


                Comment

                • Leor Zolman

                  #9
                  Re: C++ friend function

                  On Tue, 13 Apr 2004 03:23:17 +0200, "Der Andere" <matieuloeschmi ch@gmx.net>
                  wrote:
                  [color=blue][color=green][color=darkred]
                  >> > Errh, no, I didn't fix it. I've still got it.
                  >> > I've never had this kind of problem with my compiler.
                  >> > But if it works on your computer, the fault may be in my system, not in[/color][/color]
                  >the[color=green][color=darkred]
                  >> > code?![/color]
                  >>
                  >> What compiler is it, and what version? I gather that with Visual C++,
                  >> anything before 7.1 was pretty crappy.[/color]
                  >
                  >Oh, I've got Visual C++ 6.0. So maybe Microsoft is the problem, not me ;-)[/color]

                  Anytime the words "friend function", "strange error" and "MSVC 6" are
                  uttered together, there's a good chance you're dealing with the infernal
                  "friend" bug in VC6. If you haven't yet, go download the latest service
                  pack (it is up to Service Pack 6 now) at:

                  Learn with interactive lessons and technical documentation, earn professional development hours and certifications, and connect with the community.


                  -leor


                  --
                  Leor Zolman --- BD Software --- www.bdsoft.com
                  On-Site Training in C/C++, Java, Perl and Unix
                  C++ users: download BD Software's free STL Error Message Decryptor at:
                  An STL Error Decryptor for C++ by Leor Zolman of BD Software - available to download here

                  Comment

                  • Buster

                    #10
                    Re: C++ friend function

                    Der Andere wrote:
                    [color=blue][color=green]
                    >>What compiler is it, and what version? I gather that with Visual C++,
                    >>anything before 7.1 was pretty crappy.[/color]
                    >
                    > Oh, I've got Visual C++ 6.0. So maybe Microsoft is the problem, not me ;-)[/color]

                    Maybe so. I'm no expert.

                    Some things to try, without altering the correctness of your code:

                    (i) Add a forward declaration of the << overload before the definition
                    of the class of which it is a friend.

                    (ii) Define the friend function inside AVL tree class, so that it looks
                    a bit like an inline member function definition.
                    [color=blue][color=green]
                    >>If I see any problems with the
                    >>code you posted I'll let you know.[/color]
                    >
                    > Thanks![/color]

                    --
                    Regards,
                    Buster.

                    Comment

                    • Buster

                      #11
                      Re: C++ friend function

                      Buster wrote:
                      [color=blue]
                      > Der Andere wrote:
                      >[color=green]
                      >> Oh, I've got Visual C++ 6.0. So maybe Microsoft is the problem, not me
                      >> ;-)[/color]
                      >
                      > Maybe so. I'm no expert.[/color]

                      Looks like we're in the right place. Follow Leor's advice, not mine!

                      --
                      Regards,
                      Buster.

                      Comment

                      • Der Andere

                        #12
                        Re: C++ friend function

                        > >> > Errh, no, I didn't fix it. I've still got it.[color=blue][color=green][color=darkred]
                        > >> > I've never had this kind of problem with my compiler.
                        > >> > But if it works on your computer, the fault may be in my system, not[/color][/color][/color]
                        in[color=blue][color=green]
                        > >the[color=darkred]
                        > >> > code?!
                        > >>
                        > >> What compiler is it, and what version? I gather that with Visual C++,
                        > >> anything before 7.1 was pretty crappy.[/color]
                        > >
                        > >Oh, I've got Visual C++ 6.0. So maybe Microsoft is the problem, not me[/color][/color]
                        ;-)[color=blue]
                        >
                        > Anytime the words "friend function", "strange error" and "MSVC 6" are
                        > uttered together, there's a good chance you're dealing with the infernal
                        > "friend" bug in VC6. If you haven't yet, go download the latest service
                        > pack (it is up to Service Pack 6 now) at:
                        >
                        >[/color]
                        Learn with interactive lessons and technical documentation, earn professional development hours and certifications, and connect with the community.


                        Indeed. That was the problem. I've just installed the service pack and the
                        compiler issues no errors :-))

                        Regards,
                        Matthias


                        Comment

                        Working...