Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
1

Как правильно использовать friend для доступа к экземпляру класса

21.12.2011, 23:45. Показов 2313. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток. Проблема - нужно из одного класса обратиться к методам экземпляра другого класса
знаю, что для этого нужно как-то использовать friend, а как - понять не могу

Скажем, есть класс index
C++
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
class index
{
friend class indarray;  
    int *swapmas ;
    int size_;
public: 
    
    index(int n)
    {
        swapmas = new int(n);
        size_ = n;
        for(int i = 0; i<n; ++i)
        {
            swapmas[i] = n-i;
        }
    }
    int operator[](int i)
    {
        return swapmas[i];
    }
    int size()
    {
        return size_;
    }
};
(экземпляр класса назовём ind), к его методам нужно братиться в operator=
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class indarray
{
    valarray &val;
    index &ind;
 
friend class valarray;
friend class index;
 
public:
    indarray(valarray &val_, index &ind_):val(val_), ind(ind_){}
 
    void operator = (valarray valar)
    {
        for(int i = 0; ind. //тут пишет, что члены недоступны. А очень хочется получить поле size_ через метод size
    }
};
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.12.2011, 23:45
Ответы с готовыми решениями:

friend функции не имеют доступа к private элементам класса, почему?
Учусь по Лафоре Р. - Объектно-ориентированное программирование в С++ (Классика Computer Science) -...

Как правильно использовать классы? Как вывести значение класса на экран?
Всех приветствую. Делаю задание по книге. По заданию нужно завести класс, в котором хранится...

Явная специализация для friend функции класса
Как создать специализацию для какого-то конкретного типа на примере данной функции? template...

При перегрузке оператора для класса не получается использовать имя переменной такое же, как в описании класса
Описал первый класс,затем - описал второй класс, используя первый,и когда начал перезагружать...

10
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
21.12.2011, 23:49 2
Если вы хотите из класса A обратиться к закрытым полям\метода класса B, то класс A должен быть другом класса B. т.е. в декларации класса B вы должны сказать, что класс A будет его другом.

C++
1
2
3
4
5
6
class B
{
  ...
  friend class A; // из-за этой строчки ко всем методам\членам класса B можно обращаться, находясь в классе A
  ...
};
У вас вроде так и сделано. Только еще "лишняя" дружба в другую сторону добавлена.
Какие у вас проблемы то?
0
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
21.12.2011, 23:53  [ТС] 3
C++
1
 index &ind;
не работает обращение ind.size()/ind.size_ и т.д. компилятор пишет, что "члены недоступны"
Причём, обращение index.size и подобные (то есть по имени класса, а не по его экземпляру) работают
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
22.12.2011, 00:01 4
MS VS 8, все компилится. Может у вас что-то древнее и оно не понимает ключевого слова friend?
В чем пишите?

C++
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
class Index
{
  friend class FriendOfIndex;
 
  int m_size;
 
public:
  int size() {}
};
 
class FriendOfIndex
{
  Index* m_index;
 
public:
  void F()
  {
    m_index->size(); // ok
    m_index->m_size; // ok;
  }
};
 
int main()
{
  Index index;
  FriendOfIndex friendOfIndex;
 
  return 0;
}
да и зачем вам эти френды? что мешает использовать публичные ф-ии класса?
0
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
22.12.2011, 00:04  [ТС] 5
Vs 2010

Добавлено через 33 секунды
C++
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
#include "stdafx.h"
#include <iostream>
using namespace std;
 
 
class valarray
{
    int *mas;
    int size;
    
 
    /*~valarray()
    {
        delete[] mas;
    }*/
 
public:
    valarray(int n)
    {
        mas = new int[n];
        size =  n;
        for (int i = 0; i<size; ++i)
            mas[i] = rand();
    }
 
    void print()
    {
        //cout<<"\nМассив:\n";
        for(int i = 0; i<size; ++i)
            cout<<'['<<i<<"] = "<<mas[i]<<"\n";
    }
 
    int operator[](int n)
    {
        return mas[n];
    }
    indarray operator[](index t)
    {
        return indarray(*this, t);
    }
};
 
class indarray
{
    valarray &val;
    index &ind;
 
friend class valarray;
friend class index;
 
public:
    indarray(valarray &val_, index &ind_):val(val_), ind(ind_){}
 
    void operator = (valarray valar)
    {
        for(int i = 0; ind.size(); ++i) //тут пишет, что члены недоступны. А очень хочется получить поле size_ через метод size
    }
};
 
 
 
 
class index
{
friend class indarray;  
    int *swapmas ;
    int size_;
public: 
    
    index(int n)
    {
        swapmas = new int(n);
        size_ = n;
        for(int i = 0; i<n; ++i)
        {
            swapmas[i] = n-i;
        }
    }
    int operator[](int i)
    {
        return swapmas[i];
    }
    int size()
    {
        return size_;
    }
};
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(0, "Rus");
    valarray v(10),v1(10);
    index ind(10);
    cout<<"Массив v: \n";
    v.print();
//  v[ind] = v1; // v[ind[i]] = v1[i]
    return 0;
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
22.12.2011, 00:10 6
C++
1
2
3
4
        void operator = (valarray valar)
        {
                for(int i = 0; ind.size(); ++i) //тут пишет, что члены недоступны. А очень хочется получить поле size_ через метод size
        }
Недоступен публичный метод size()? не настораживает?

как-то у вас все запущено. это вообще не компилится.
и вот почему не должно компилится:

у вас идут определения классов в такой порядке:
C++
1
2
3
class A { тут реализация методов };
class B {тут реализация методов };
class C {тут реализация методов };
Причем реализация методов сразу в классе. и вот в методах класса A вы обращаетесь к методам класса B. Но в классе A еще ничего не известно о классе B; Смотрите на строку 37 indarray определен ниже. в строке 37 компилятор еще ничего не знает об этом классе.

Вам поможет вот что:
C++
1
2
3
4
5
6
7
8
9
10
class A { тут объявления методов };
class B {тут объявления методов };
class C {тут объявления методов };
 
// А тут реалицация методов
A::xxx() {}
 
B::xxx() {}
 
C::xxx() {}
0
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
22.12.2011, 00:14  [ТС] 7
Я думал, оно автоматом всё подхватит...сказывается недостаток теории(
можно про синтаксис по-подробней?
на примере
C++
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
class index
{
friend class indarray;  
    int *swapmas ;
    int size_;
public: 
    
    index(int n)
    {
        swapmas = new int(n);
        size_ = n;
        for(int i = 0; i<n; ++i)
        {
            swapmas[i] = n-i;
        }
    }
    int operator[](int i)
    {
        return swapmas[i];
    }
    int size()
    {
        return size_;
    }
};
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
22.12.2011, 00:28 8
Вам френды нигде не нужны в общем-то. вот ваш компилябельный код:
C++
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "stdafx.h"
#include <iostream>
using namespace std;
 
class index
{
  int *swapmas;
  int size_;
public: 
  index(int n)
  {
    swapmas = new int(n);
    size_ = n;
    for(int i = 0; i<n; ++i)
    {
      swapmas[i] = n-i;
    }
  }
 
  int operator[](int i)
  {
    return swapmas[i];
  }
  int size()
  {
    return size_;
  }
};
 
 
class valarray; // из-за этого можно в декларации класса indarray использовать ссылки и указатели на valarray
 
 
class indarray
{
  valarray& val;
  index& ind;
 
public:
  indarray(valarray& val_, index& ind_);
  void operator = (const valarray& valar);
};
 
class valarray
{
  int *mas;
  int size;
        
public:
  valarray(int n);
  //~valarray();
 
  void print();
  int operator[](int n);
  indarray operator[](index t);
};
 
indarray::indarray(valarray &val_, index &ind_)
  : val(val_)
  , ind(ind_)
{
}
 
void indarray::operator = (const valarray& valar)
{
  for(int i = 0; ind.size(); ++i) //тут пишет, что члены недоступны. А очень хочется получить поле size_ через метод size
  {
  }
}
 
valarray::valarray(int n)
{
  mas = new int[n];
  size =  n;
  for (int i = 0; i<size; ++i)
    mas[i] = rand();
}
 
/*
valarray::~valarray()
{
  delete[] mas;
}
*/
 
void valarray::print()
{
  //cout<<"\nМассив:\n";
  for(int i = 0; i<size; ++i)
    cout<<'['<<i<<"] = "<<mas[i]<<"\n";
}
 
int valarray::operator[](int n)
{
  return mas[n];
}
 
indarray valarray::operator[](index t)
{
  return indarray(*this, t);
}
 
int _tmain(int argc, _TCHAR* argv[])
{
  setlocale(0, "Rus");
  valarray v(10),v1(10);
  index ind(10);
  cout<<"Массив v: \n";
  v.print();
  //v[ind] = v1; // v[ind[i]] = v1[i]
  return 0;
}
Корректность уже сами смотрите
0
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
22.12.2011, 00:36  [ТС] 9
То есть смысл в том, что нельзя использовать то, что не определено "выше"
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
22.12.2011, 00:39 10
да. именно так. указатели и ссылки хранить или передавать в другие ф-ии можно, если выше есть хотябы декларация класса.
создавать экземпляры класса, обращаться к методам через указатель или ссылку, кастить к базовым классам, использовать sizeof(UnknownClass) - нельзя, если класс не определен выше.
1
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
22.12.2011, 00:40  [ТС] 11
Спасибо
0
22.12.2011, 00:40
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.12.2011, 00:40
Помогаю со студенческими работами здесь

Исправить реализацию friend-функции для шаблонного класса
Здравствуйте! Есть шаблонный класс, для которого нужно перегрузить операторы ввода/вывода....

Как объявить friend функцию класса
как это оформить, чтобы работало // ----------&gt; one.h #include &quot;two.h&quot; #ifndef ONE_H_INCLUDED...

Передача свойства одного экземпляра класса другому экземпляру класса
#include &lt;tchar.h&gt; class A { public: A(); int aVar; }; class B : public A

Посмотрите, где ошибка с перегрузкой оператора и friend функцией для класса
Приветствую. :rose:Спасибо заранее, что обратили внимание на эту тему.:thank_you: Работаю в VS...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru