Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 272
#1

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

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

Доброго времени суток. Проблема - нужно из одного класса обратиться к методам экземпляра другого класса
знаю, что для этого нужно как-то использовать 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.12.2011, 23:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как правильно использовать friend для доступа к экземпляру класса (C++):

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

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

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

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

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

Как переделать friend-перегрузки ввода/вывода в метод класса? - C++
Доброго времени суток! Есть вопрос: как переделать френдовые перегрузки ввода\вывода в метод класса? Или же как шаблонить френдовые...

10
DU
1483 / 1129 / 45
Регистрация: 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
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 272
21.12.2011, 23:53  [ТС] #3
C++
1
 index &ind;
не работает обращение ind.size()/ind.size_ и т.д. компилятор пишет, что "члены недоступны"
Причём, обращение index.size и подобные (то есть по имени класса, а не по его экземпляру) работают
0
DU
1483 / 1129 / 45
Регистрация: 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
IcyWind
8 / 8 / 2
Регистрация: 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
1483 / 1129 / 45
Регистрация: 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
IcyWind
8 / 8 / 2
Регистрация: 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
1483 / 1129 / 45
Регистрация: 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
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 272
22.12.2011, 00:36  [ТС] #9
То есть смысл в том, что нельзя использовать то, что не определено "выше"
0
DU
1483 / 1129 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
22.12.2011, 00:39 #10
да. именно так. указатели и ссылки хранить или передавать в другие ф-ии можно, если выше есть хотябы декларация класса.
создавать экземпляры класса, обращаться к методам через указатель или ссылку, кастить к базовым классам, использовать sizeof(UnknownClass) - нельзя, если класс не определен выше.
1
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 272
22.12.2011, 00:40  [ТС] #11
Спасибо
0
22.12.2011, 00:40
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.12.2011, 00:40
Привет! Вот еще темы с ответами:

Как правильно использовать sort() для сортировки массива? - C++
Хочу отсортировать массив char ch, можно ли это сделать с помощью стандартной библиотеки или обязательно использовать strcmp?? ...

Как правильно использовать Указатели для массива (ошибки в программе)? - C++
Необходимо переписать программу правильно, чтобы использовались указатели. Помогите, пожалуйста!!! Примерный (с ошибками код): ...

Как правильно перегрузить оператор для шаблона класса - C++
Имеется такой шаблон: template&lt;int Low = 0, int High = 1000&gt; class Diapazon { }; Внутри него много всего, что уже работает,...

Как вызвать функцию-член правильно для класса Person - C++
Задача простая, ввести фамилию и имя и вывести их. Подскажите, как правильно написать функцию вывода print(). Если один параметр...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru