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

есть вложенный класс который является другом объемлюющего и всё это должно компилиться. - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.83
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
29.06.2011, 16:01     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #1
Сперва логика:
Есть класс matrix. И есть класс diagonal; так я поразмыслил и пришёл к выводу, что объект diagonal в отрыве от объекта matrix существовать не может и поэтому сделал diagonal вложенным в matrix

Кроме того, класс diagonal должен иметь доступ к полям matrix, поэтому вложенный класс друг для объемлюющего

Наконец вся эта херь- шаблон.

Два вопроса поэтому. Как сие реализовать?

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
//Опережающее объявление
template< typename T >
class diagonal;
 
 
template <class T>
class matrix {
 public:
  friend class diagonal<T>;
 private:
  //Тут вот приватные поля, к ним класс диагональ должен иметь доступ
};
 
 
//Короче тут я не могу компильнуть никак
template <class T>
class matrix<T>::diagonal {
 public:
  diagonal (){
  //ЗДесь код с доступом  к закрытым полям класса matrix
  }
};
 
 
int main () {
 matrix <int> k;
 //matrix<int>::diagonal di;
}
;ругается на определение класса diagonal

И второе: я хочу чтобы при объявлении класса diagonal было видно: ага этот объект принадлежит
такому-то объекту класса matrix (такой-то матрице; то есть не просто гипотетическому классу
matrix, а конкретной матрице; вот не так вот
C++
1
  matrix<int>::diagonal di;
А как-то так, что ли
C++
1
k.diagonal di;
)спасибо, кто поможет. Реагировать только на реализацию!

Добавлено через 19 часов 55 минут
Никто не знает?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.06.2011, 16:01     есть вложенный класс который является другом объемлюющего и всё это должно компилиться.
Посмотрите здесь:

this это адресс объекта, а *this это сам объект. я всё правельно понял? C++
Может ли объемлющий класс иметь неограниченный доступ к элементам вложенного класса? А вложенный класс — к элементам объемлющего? C++
вложенный класс C++
C++ Вложенный класс
C++ вложенный класс
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
30.06.2011, 14:01     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #21
kravam, В СТЛ крайне мало плохой реализации. Например в GCC STL 4.5.2 меня взбесило только одно.

C++
1
2
3
      _Rep*
      _M_rep() const
      { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
Где Rep вложенная структура, хранящая в себе поля

C++
1
2
3
4
5
6
    static const size_type  _S_max_size;
    static const _CharT _S_terminal;
 
    // The following storage is init'd to 0 by the linker, resulting
        // (carefully) in an empty string with one reference.
        static size_type _S_empty_rep_storage[];
Проивзодная от структуры.

C++
1
2
3
4
5
6
      struct _Rep_base
      {
    size_type       _M_length;
    size_type       _M_capacity;
    _Atomic_word        _M_refcount;
      };
_M_Data() - функция

C++
1
2
3
4
5
      mutable _Alloc_hider  _M_dataplus;
 
      _CharT*
      _M_data() const
      { return  _M_dataplus._M_p; }
Где _Alloc_hider

C++
1
2
3
4
5
6
7
      struct _Alloc_hider : _Alloc
      {
    _Alloc_hider(_CharT* __dat, const _Alloc& __a)
    : _Alloc(__a), _M_p(__dat) { }
 
    _CharT* _M_p; // The actual data.
      };
Где _Alloc соответственно шаблонный тип аллокатора.

А вот boost к примеру уже содержит множество нетривиальной реализации.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
01.07.2011, 00:01  [ТС]     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #22
В общем, ребята, я думал-думал и пришёл к выводу, что вложенный класс никакой функциональности новой не прибавляет, а только он нужен чтобы глазу разработчика было удобнее.

Действительно, если есть класс A и в него вложен класс B, то B не может воспользоваться ни одним из методов класса A, ни одним из полей (елси, конечно, они не открыты). Так, если он к ним обращается просто по имени, то компилятор ищет такие поля в самом классе B и не может найти, если использует A::, то компилятор говорит, что класс A не является базовым для класса B. Тут, понятно, выход объявлять класс B дружественным A, а тогда от вложенности смысла нет. Не то чтобы я недоволен, просто доразбирываюсь.

Ну и понятно, что классу A ни жарко ни холодно от того, что в нём объявлен класс B (не объект класса B, а сам класс!). Так ведь? Или всё ж таки вложенность даёт нечто, чего не добиться с помощью других способов взаимодействия классов, например, дружественности? Вроде не даёт.
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
01.07.2011, 14:31     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #23
Цитата Сообщение от kravam Посмотреть сообщение
Так ведь? Или всё ж таки вложенность даёт нечто, чего не добиться с помощью других способов взаимодействия классов, например, дружественности? Вроде не даёт.
Вложенность позволяет ограничить "область действия" класса. Например, если написать так, то класс internal не будет доступен никому.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class external {
private:
    class internal {
    };
 
private:
    internal in;
};
 
int main() {
    external a;
    //external::internal b; // error: ‘class external::internal’ is private
 
    return 0;
}
Если написать это как public, то класс external будет действовать как пространство имен.
Выгоды есть. Как уже говорилось выше классы создаются для удобства.
Конкретный пример с матрицей, когда нужен вложенный класс, если матрица реализуется на основе Си-подобных массивов. Интуитивно понятным является обращение к элементу матрицы через оператор [], то есть matrix[i][j]. В Си++ существует возможность перегрузить operator[]. Однако обращение как к двумерному массиву к классу запрещено. Поэтому создается вложенный класс "строка", для него также перегружается operator[]. Перегруженный operator[] в классе "матрица" возвращает ссылку на класс "строка". Таким образом фактически производится вызов row = matrix.operator[](i), element = row.operator[j]. Как я уже отметил, matrix.operator[](i) возвращает ссылку на класс "строка" и только тогда уже возможен вызов row.operator[j].

Ну как-то так, в общем смысл всегда есть

Ну и очень грубый пример:
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
#include <iostream>
 
class external {
private:
    class internal {
        public:
            int operator[](int j) {
                return a[j];
            }
 
            int a[2];
    };
 
public:
    external() {
        in[0].a[0] = 0;
        in[0].a[1] = 1;
        in[1].a[0] = 2;
        in[1].a[1] = 3;
    }
 
    internal& operator[](int i) {
        return in[i];
    }
 
private:
    internal in[2];
};
 
int main() {
    external a;
    // external::internal b; error: ‘class external::internal’ is private
    std::cout << a[0][0] << a[0][1] << a[1][0] << a[1][1] << std::endl;
 
    return 0;
}
При этом класс 'internal' по-прежнему не доступен вне класса 'external'.

Пожалуй, еще одним из очень распространенных примеров являются списки, деревья и так далее, где вложенным классом является класс узла.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
02.07.2011, 18:56  [ТС]     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #24
я, наверное был непонятен в последнем своём посту. Так вот, я искал то, что можно сделать с помощью вложенности и нельзя без неё. То что вы напечатили- не аргумент, ибо вот
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
#include <iostream>
 
        class internal {
                public:
                        int operator[](int j) {
                                return a[j];
                        }
 
                        int a[2];
        };
 
 
class external {
 
public:
        external() {
                in[0].a[0] = 0;
                in[0].a[1] = 1;
                in[1].a[0] = 2;
                in[1].a[1] = 3;
        }
 
        internal& operator[](int i) {
                return in[i];
        }
 
private:
        internal in[2];
};
 
int main() {
        external a;
        // external::internal b; error: ‘class external::internal’ is private
        std::cout << a[0][0] << a[0][1] << a[1][0] << a[1][1] << std::endl;
 
        getchar (); 
        return 0;
}
Без всякой вложенности. Извините, если что не так.
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
02.07.2011, 19:09     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #25
класс диагональ должен быть вложенным и приватным, так как ни один пользователь не захочет общаться с матрицей через какие-то классы посредники, тем более диагонали. Это деталь реализации и открывать её пользователю нельзя. Даже если это было что-то менее извращённое типа векторов, строк, или столбцов всё равно надо вкладывать и закрывать
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
02.07.2011, 19:22  [ТС]     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #26
Это я понял. Я и сам пытался с самого начала сделать класс diagonal ложенным в класс matrix, если кто не заметил. Имея ввиду, что диагональ вложена в матрицу
(Это только у Льюиса Кэррола улыбка может быть отдельно от кота)
Но я другой вопрос поставил.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
02.07.2011, 20:17     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #27
kravam, вы никак по-другому не скроете какой-либо класс от пользователя, кроме как сделав его вложенным в другой класс, в приватную секцию. Это ответ на ваш вопрос?
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
02.07.2011, 20:28  [ТС]     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #28
Это ответ, но это крайне непонятный ответ, несмотря на его краткость.
Дядька-конечный пользователь увидит класс matrix и увидит в нём вложенный класс diagonal. Хм, и какое тут к матери, сокрытие? То, что он пользоваться им не сможет без того, чтобы не залезть в него своими толстыми пальцами и не поковыряться- это да.

...Ну так я и говорю: объявляем класс diagonal внешним, пишем в комментах "сюда не лезть" и всё на этом. Никакой вложенности не надо.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
02.07.2011, 20:41     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #29
kravam, эээ. Что, бл...?? А что в вашем понимании сокрытие? Шифрование исходного кода, что-ли? Защита его от вмешательства? Да нифига, читайте про принципы ООП, если вы пока так думаете о сокрытии.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
02.07.2011, 20:52  [ТС]     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #30
А в вашем понимании что такое сокрытие? Это:
Цитата Сообщение от silent_1991 Посмотреть сообщение
вы никак по-другому не скроете какой-либо класс от пользователя, кроме как сделав его вложенным в другой класс, в приватную секцию.
Второй раз пишу: я эту херь сделаю и безо всякой вложенности. Делаю внешний (читай: обыкновенный класс и пишу: "сюда не лезть, кто не влез, тот сам дурак")

Вот так я реализую вашу идею безо всякой вложенности. Блин, комментарии к коду никто не отменял в конце концов
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
02.07.2011, 20:55     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #31
Цитата Сообщение от kravam Посмотреть сообщение
обыкновенный класс и пишу: "сюда не лезть, кто не влез, тот сам дурак"
ОМГ. Если это сокрытие, и если, по-вашему, это эквивалентно предложенному мной варианту, то мне не о чем больше с вами разговаривать, продолжайте быдлокодить.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
02.07.2011, 20:59  [ТС]     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #32
А мне всё равно, как это назвать- сокрытие -не сокрытие. Важно, что это по сути. Оно то, что вы предложили. И да, эквивалентно. Продолжаю быдлокодить.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
02.07.2011, 21:01     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #33
kravam, ага, а ещё можете про спецификаторы доступа забыть, заменив их на комментарии
C++
1
// Эти методы можно вызывать
и
C++
1
// Пожалуйста, не изменяйте явно эти поля!
Удачи.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
02.07.2011, 21:18  [ТС]     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #34
Не, ну я просто хотел узнать, исчерпывается ли вышесказанным польза от вложенности. Эта ВСЯ польза? Ещё раз Это вся польза? Больше никакой пользы нет?

А так-то я в третий раз повторяю, я и сам сделаю класс "диагональ" вложенным в класс "матрица", я в первом сообщении, по-моему, сказал, что я так и делаю. Интуиция, знаете ли.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
02.07.2011, 21:20     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #35
kravam, да, в плюсах, в отличие от, например, джавы, это вся польза.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
02.07.2011, 21:25  [ТС]     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #36
Большое вам спасибо!!!
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.07.2011, 12:25     есть вложенный класс который является другом объемлюющего и всё это должно компилиться.
Еще ссылки по теме:

шаблонный вложенный класс в .cpp C++
Вложенный (внутренний) класс (inner class) C++
C++ Обработка строк. Всё, что находится между /*...*/ не должно выводиться

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

Или воспользуйтесь поиском по форуму:
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
03.07.2011, 12:25     есть вложенный класс который является другом объемлюющего и всё это должно компилиться. #37
Цитата Сообщение от kravam Посмотреть сообщение
Без всякой вложенности. Извините, если что не так.
Читать надо внимательнее. В таком случае класс internal доступен. Вполне возможно создать объект класса internal, когда он вложенный такой возможности нет.
Yandex
Объявления
03.07.2011, 12:25     есть вложенный класс который является другом объемлюющего и всё это должно компилиться.
Ответ Создать тему
Опции темы

Текущее время: 16:26. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru