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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.83
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,508
#1

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

29.06.2011, 16:01. Просмотров 1665. Ответов 36
Метки нет (Все метки)

Сперва логика:
Есть класс 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 минут
Никто не знает?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.06.2011, 16:01
Здравствуйте! Я подобрал для вас темы с ответами на вопрос есть вложенный класс который является другом объемлюющего и всё это должно компилиться. (C++):

сегодня наконец то понял что такое КЛАСС, и ОБЪЕКТ. понято всё, кроме одного - зачем всё это? в смысле, можно же без этого? так зачем жизнь усложнять? - C++
сегодня наконец то понял что такое КЛАСС, и ОБЪЕКТ. понято всё, кроме одного - зачем всё это? в смысле, можно же без этого? так зачем жизнь...

Зависает программа, хотя используется BeginInvoke, и всё должно считаться в другом потоке - C#
У меня есть программа которая моделирует физ процесс, иногда делает это долго, чтобы на форму не ставилось Программа не отвечает, решил...

Как связать всё это друг с другом? - FoxPro
По методичке создала базу данных. По второй методичке создала формочку, кнопочки. Формочка из текстбокс, кнопки перехода от одной...

Является ли это ОО кодом? Что должно быть в protected? - ООП и паттерны
Добрый день. Пара вопросов есть. Первый вопрос. Есть класс, который в private содержит объекты других классов, те в свою очередь тоже...

Вложенный запрос вернул больше одного значения Это запрещено, когда вложенный запрос следует после =, !=, <, < - SQL Server
Здравствуйте,проблема вот в чем,при добавление записи в таблицу,первая запись добавляется,а при добавление второй выдает что &quot;вложенный...

Сделать класс Car который является наследник от AComponent - C#
Суть задачи, сделать некий класс Car который является наследник от AComponent AComponent – это абстрактный класс, который реализует...

36
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,508
29.06.2011, 21:52  [ТС] #16
По-моему у меня код как раз упрощается. Конечный, конечно, код.

Добавлено через 3 минуты
Ради того, чтобы у меня был простой код в main, я делаю сложный код в классе. Может, неумело. Но это уже второй вопрос.
0
Bers
Заблокирован
29.06.2011, 21:54 #17
Цитата Сообщение от kravam Посмотреть сообщение
По-моему у меня код как раз упрощается. Конечный, конечно, код.
По ВАШЕМУ

Тогда почему, другим участникам форума вас так трудно понять?

Не забывайтесь - если вы не один, то при написании кода вы должны учитывать то, как ваш код будут читать другие. Код должен быть максимально прост не только для вас, но и для других.
Иначе, вы - не командный игрок.
0
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,508
29.06.2011, 22:11  [ТС] #18
Потому, что я стормозил. ТАК торможу я довольно редко. Блин, вчера глаза слипались и я создал такую тему вместо того, чтобы вот так спросить:

Вкратце: класс X должен и быть вложенным в другой класс Y и друг ему.

Просто. И не было бы этой бодяги.
Кстати, понять меня относительно легко при моём-то коде. Потому, что я работаю над тем, чтобы он был понятен. Пишу комменты, сокращаю до минимума делаю отступы и прочая. Согласиться с кодом- да, почему-то трудно.
Но-во-первых, я чисто и честно русским языком просил не лезть в логику проекта, а только в его реализацию, нет тут же посыпались советы. Во-вторых, пишу же русским языком: КОД СЫРОЙ.

Вот не у кого же не хватает ума залезть в исходники того же STL и прочая. Вы уверены, что их реализация вас устроит? А ко мне лезут, не просишь, а лезут. Выдам на-гора конечный продукт, тогда лезьте.
Но я сам виноват, не буду без надобности выкладывать проекты тем более сырые. Они мне слишком тяжело даются для этого.
...А так-то да, игрок я не командный потому, что я самоучка.
0
Jupiter
Каратель
Эксперт С++
6566 / 3987 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
29.06.2011, 22:18 #19
Удобность интерфейса,
удобство это СТЛ) вот на протяжении учебного года жизнь заставила написать
matrix.h
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
#ifndef MATRIX_H
#define MATRIX_H
 
#include <vector>
 
class Matrix {
 
    std::vector< std::vector<double> > matr;
 
public:
 
    Matrix(unsigned rows = 1, unsigned cols = 1, double fill = 0.0);
    Matrix(unsigned rows, unsigned cols, double (*func)(double,double));
    Matrix(const Matrix &);
 
    void resize(unsigned = 1, unsigned = 1, double = 0.0);
 
    unsigned Row() const { return matr.size(); }
    unsigned Col() const { return matr[0].size(); }
 
    double &       operator () (unsigned i, unsigned j);
    const double & operator () (unsigned i, unsigned j) const;
 
    Matrix         operator +  (const Matrix &) const;
    const Matrix & operator += (const Matrix & rhs);
 
    Matrix         operator -  (const Matrix &) const;
    const Matrix & operator -= (const Matrix & rhs);
 
    Matrix         operator *  (const Matrix &) const;
    const Matrix & operator *= (const Matrix & rhs);
 
    void RowExChange(unsigned i, unsigned j);
    void ColExChange(unsigned i, unsigned j);
 
    std::vector< double > GetRow            (unsigned i) const;
    std::vector< double > GetCol            (unsigned i) const;
    std::vector< double > GetDiagonal       (unsigned i, unsigned j) const; /* '\' */
    std::vector< double > GetBackDiagonal   (unsigned i, unsigned j) const; /* '/' */
 
    void SetRow              (unsigned i, const std::vector< double > &);
    void SetCol              (unsigned i, const std::vector< double > &);
    void SetDiagonal         (unsigned i, unsigned j, const std::vector< double > &);
    void SetBackDiagonal     (unsigned i, unsigned j, const std::vector< double > &);
 
    void SortRow             (unsigned i, const char c = '<'); // 1 2 3 4
    void SortCol             (unsigned i, const char c = '<');
    void SortDiagonal        (unsigned i, unsigned j, const char c = '<');
    void SortBackDiagonal    (unsigned i, unsigned j, const char c = '<');
 
    void RotateRow           (unsigned i, unsigned on, bool left = true);
    void RotateCol           (unsigned i, unsigned on, bool up = true);
    void RotateDiagonal      (unsigned i, unsigned j, unsigned on, bool left = true);
    void RotateBackDiagonal  (unsigned i, unsigned j, unsigned on, bool left = true);
 
};
 
#endif // MATRIX_H
 
/*
  GetDiagonal(3, 4) --> 1 2 3 4
  0 1 0 0 0
  0 0 2 0 0
  0 0 0 3 0
  0 0 0 0 4
  0 0 0 0 0
 
  GetBackDiagonal(3, 4) --> 1 2 3 4
  0 0 0 0 0
  0 0 0 0 4
  0 0 0 3 0
  0 0 2 0 0
  0 1 0 0 0
*/
0
fasked
Эксперт С++
4963 / 2543 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
30.06.2011, 10:15 #20

Не по теме:

Цитата Сообщение от kravam Посмотреть сообщение
Вот не у кого же не хватает ума залезть в исходники того же STL и прочая. Вы уверены, что их реализация вас устроит?
Почему же.. и вполне устраивает кстати.


По теме, раз диагональ так нужна в виде отдельной сущности, то эту диагональ надо либо возвращать в методе класса матрицы, либо делать диагональ членом класса матрицы, а не так, чтобы диагональ жила отдельно от матрицы.
1
ForEveR
В астрале
Эксперт С++
7988 / 4747 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 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 к примеру уже содержит множество нетривиальной реализации.
0
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,508
01.07.2011, 00:01  [ТС] #22
В общем, ребята, я думал-думал и пришёл к выводу, что вложенный класс никакой функциональности новой не прибавляет, а только он нужен чтобы глазу разработчика было удобнее.

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

Ну и понятно, что классу A ни жарко ни холодно от того, что в нём объявлен класс B (не объект класса B, а сам класс!). Так ведь? Или всё ж таки вложенность даёт нечто, чего не добиться с помощью других способов взаимодействия классов, например, дружественности? Вроде не даёт.
0
fasked
Эксперт С++
4963 / 2543 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 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'.

Пожалуй, еще одним из очень распространенных примеров являются списки, деревья и так далее, где вложенным классом является класс узла.
1
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,508
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;
}
Без всякой вложенности. Извините, если что не так.
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
02.07.2011, 19:09 #25
класс диагональ должен быть вложенным и приватным, так как ни один пользователь не захочет общаться с матрицей через какие-то классы посредники, тем более диагонали. Это деталь реализации и открывать её пользователю нельзя. Даже если это было что-то менее извращённое типа векторов, строк, или столбцов всё равно надо вкладывать и закрывать
0
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,508
02.07.2011, 19:22  [ТС] #26
Это я понял. Я и сам пытался с самого начала сделать класс diagonal ложенным в класс matrix, если кто не заметил. Имея ввиду, что диагональ вложена в матрицу
(Это только у Льюиса Кэррола улыбка может быть отдельно от кота)
Но я другой вопрос поставил.
0
silent_1991
Эксперт С++
4997 / 3055 / 149
Регистрация: 11.11.2009
Сообщений: 7,040
Завершенные тесты: 1
02.07.2011, 20:17 #27
kravam, вы никак по-другому не скроете какой-либо класс от пользователя, кроме как сделав его вложенным в другой класс, в приватную секцию. Это ответ на ваш вопрос?
0
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,508
02.07.2011, 20:28  [ТС] #28
Это ответ, но это крайне непонятный ответ, несмотря на его краткость.
Дядька-конечный пользователь увидит класс matrix и увидит в нём вложенный класс diagonal. Хм, и какое тут к матери, сокрытие? То, что он пользоваться им не сможет без того, чтобы не залезть в него своими толстыми пальцами и не поковыряться- это да.

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

Вот так я реализую вашу идею безо всякой вложенности. Блин, комментарии к коду никто не отменял в конце концов
0
02.07.2011, 20:52
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.07.2011, 20:52
Привет! Вот еще темы с ответами:

Виснет весь ПК из-за процесса который невозможно закрыть и который ест всё ЦП моего пк. - Удаление вирусов
Виснет весь ПК из-за процесса который невозможно закрыть и который ест всё ЦП моего пк. Всё началось недавно когда я попытался включить...

this это адресс объекта, а *this это сам объект. я всё правельно понял? - C++
this это адресс объекта, а *this это сам объект. я всё правельно понял?

есть 2 виртуальных инструмента,надо чтобы когда на одном меняли value чтобы и стрелка и на другом менялась и это используя rmi - Java
Привет. У меня паника! помогите мне пожааааалуйста. есть 2 виртуальных инструмента,надо чтобы когда на одном меняли value чтобы и...

Есть класс Точка. Написать метод, который будет рисовать точку на форме - C#
Есть класс Точка. Написать метод, который будет рисовать точку на форме. class Point { public int X { set; get; } ...


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

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

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