Allowing access(friend)- C++ Primer Exercise 7.32

closed account (EwCjE3v7)
I would like the function clear in Window_mgr to access the private part of Screen, but I dont know how to

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#ifndef SCREEN_H
#define SCREEN_H

#include <string>
#include <vector>

class Screen
{
public:
  friend void Window_mgr::clear(std::vector<Screen>::size_type);

  typedef std::string::size_type pos;

  Screen() = default; // needed because Screen has another constuctor

  Screen(pos ht, pos wd) : height(ht), width(wd) {}

  Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c) {}



  Screen &move(pos r, pos c)
  {
    pos row = r * width; // compute the new location
    cursor = row + c;    // move curso to the column within that row
    return *this;        // return this object as lvalue
  }

  Screen &set(char c)
  {
    contents [cursor] = c; // set the new value at the crrent cursor location
    return *this;          // return this object as an lvalue
  }

  Screen &set(pos r, pos col, char ch)
  {
    contents[r*width + col] = ch; // set specidified location to given value
    return *this;                 // return this object as an lvalue
  }




  Screen &display(std::ostream &os)
  {
    do_display(os);
    return *this;
  }

  const Screen &display(std::ostream &os) const
  {
    do_display(os);
    return *this;
  }


  char get() const
  {
    return contents[cursor];
  }

  char get(pos r, pos c) const
  {
    pos row = r * width;
    return contents[row + c];
  }

private:
  void do_display(std::ostream &os) const
  {
    os << contents;
  }

  pos cursor = 0;
  pos height = 0, width = 0;
  std::string contents;
};



class Window_mgr
{
public:
  // location ID for each screen window
  typedef std::vector<Screen>::size_type ScreenIndex;

  void clear(ScreenIndex i)
  {
    Screen &s = screens[i];
    s.contents = string(s.height * s.width, ' ')
  }

private:
  std::vector<Screen> screens{Screen(24, 80, ' ')};
};

#endif // SALES_DATA_H
Last edited on
closed account (EwCjE3v7)
Anyone???
closed account (j3Rz8vqX)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// friend class
#include <iostream>
using namespace std;

class Square;

class Rectangle {
    int width, height;
  public:
    int area ()
      {return (width * height);}
    void convert (Square a);
};

class Square {
  friend class Rectangle;
  private:
    int side;
  public:
    Square (int a) : side(a) {}
};

void Rectangle::convert (Square a) {
  width = a.side;
  height = a.side;
}
  
int main () {
  Rectangle rect;
  Square sqr (4);
  rect.convert(sqr);
  cout << rect.area();
  return 0;
}

Not my code:
http://www.cplusplus.com/doc/tutorial/inheritance/

In this example, class Rectangle is a friend of class Square allowing Rectangle's member functions to access private and protected members of Square. More concretely, Rectangle accesses the member variable Square::side, which describes the side of the square.


Edit: Just to say before errors happen:
Ensure that you've implemented a class prototype before the befriend class.
Example line 5.
Last edited on
closed account (EwCjE3v7)
Yea but as you can see I`m also defining a Screen variable in Window_mgr


EDIT:

@EVERYONE

Look let me give you another example to make it easier.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class cls1 // my first class
{
public:
	void nothing(cls2 noth) // this funtion wants to access the privates of cls2
	{
		cls2.i = 5; // this
	}

private: 
	cls2 tst; // it also wants to decalre a cls2 type 
};

class cls2 // second class
{
public:
	friend void cls1::nothing(cls2); // wants to allow the fuction nothing in cls1 to access the stuff after its private
private:
	int i = 0; // wants to allow perms to this
};
Last edited on
You could always use friend class Window_mgr; rather than going with the finer granularity of a single method. It isn't ideal, but it works.

I find it hard to believe your Screen type doesn't supply a method to query height or width. If it did, you wouldn't require the 'friend' at all.

1
2
3
4
5
    void clear(std::vector<Screen>::size_type i)
    {
        Screen& s = screens[i];
        s = Screen(s.get_height(), s.get_width(), ' ');
    }


closed account (EwCjE3v7)
@cire Thank you for your quick reply, this is from my book, and these are the instructions my book gives:

1.First define the Window_mgr class, which declares but cannot define, clear.
2. Next define class Screen, including a friend declaration for clear
3. Finally define clear, which can now refer to the members in Screen.

Now it does not say anything about the screens vector thats is defined in Window_mgr.

I have not made this, its from C++ primer 5th edition. Is this false or ...?

I do not know what to do to fix this.


EDIT:

Fixed it!!! :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#ifndef SCREEN_H
#define SCREEN_H

#include <string>
#include <vector>

class Screen;

typedef std::vector<Screen>::size_type ScreenIndex;

class Window_mgr
{
public:
  void clear(ScreenIndex);

private:
  std::vector<Screen> screens{(24, 80, ' ')};
};

class Screen
{
public:
  friend void Window_mgr::clear(std::vector<Screen>::size_type);

  typedef std::string::size_type pos;

  Screen() = default; // needed because Screen has another constuctor

  Screen(pos ht, pos wd) : height(ht), width(wd) {}

  Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c) {}



  Screen &move(pos r, pos c)
  {
    pos row = r * width; // compute the new location
    cursor = row + c;    // move curso to the column within that row
    return *this;        // return this object as lvalue
  }

  Screen &set(char c)
  {
    contents [cursor] = c; // set the new value at the crrent cursor location
    return *this;          // return this object as an lvalue
  }

  Screen &set(pos r, pos col, char ch)
  {
    contents[r*width + col] = ch; // set specidified location to given value
    return *this;                 // return this object as an lvalue
  }




  Screen &display(std::ostream &os)
  {
    do_display(os);
    return *this;
  }

  const Screen &display(std::ostream &os) const
  {
    do_display(os);
    return *this;
  }


  char get() const
  {
    return contents[cursor];
  }

  char get(pos r, pos c) const
  {
    pos row = r * width;
    return contents[row + c];
  }

private:
  void do_display(std::ostream &os) const
  {
    os << contents;
  }

  pos cursor = 0;
  pos height = 0, width = 0;
  std::string contents;
};

void Window_mgr::clear(ScreenIndex i)
{
  Screen &s = screens[i];
  s.contents = std::string(s.height * s.width, ' ');
}

#endif // SALES_DATA_H 
Last edited on
Topic archived. No new replies allowed.