Массив как поле класса c
То есть под полем должен подразумеваться массив и с этим полем надо как то срабатывать потом. Допустим,
// предположим, что размерности обоих массивов одинаковые int a[5]; A = a;
Как то так
Регистрация: 16.12.2011
Сообщений: 2,329
Форумчанин
Регистрация: 03.01.2013
Сообщений: 388
При чем здесь вектор. Это уже из STL, а человеку, вилимо, нужно собственную реализацию.
Насколько я понял автор имел в виду вот это:
class UserClassName
private:
int *pArray;
public:
UserClassName(int _arraySize)
pArray = new int(_arraySize);
>
~UserClassName(int _arraySize)
delete pArray;
pArray = NULL;
>
>;
Пользователь
Регистрация: 21.04.2009
Сообщений: 50
да да, мне нужна собственная реализация.
class UserClassName private: int *pArray; public: UserClassName(int _arraySize) pArray = new int(_arraySize); > ~UserClassName(int _arraySize) delete pArray; pArray = NULL; > >; |
Ну здесь только вместо поля указатель, конструктор и деструктор. А как же методы доступа к полю (Get и Set) и метод существования поля (__property)?
Пример создания класса для работы с одномерными массивами
Для практики программирования Вам были предложены Задачи 2, содержащие работу со строками, одномерными и двухмерными массивами.
Полезно эти программы писать в стиле ООП, то есть задается некоторый исходный класс, назовем его ArrayIntOne, с использованием которого далее решаются поставленные задачи.
Вы можете добавлять в этот класс новые методы, либо, наследуя от него дочерний класс, создать новый.
Решение
1. Каждый класс будем сохранять как отдельный файл в общем пространстве имен, например, namespace ArrayIntOne, либо через подключение через директиву using.
2. Исходный класс назовем ArrayInt1, который будет содержать некоторые поля, конструкторы и методы. Естественно, что полями класса будут длина массива n и собственно одномерный массив a[]. Конструкторы класса необходимы для создания массивов разными способами (через ввод с клавиатуры, через генераторы случайных чисел). Методы класса — самые простые (задать или извлечь элемент массива, найти максимальный/минимальный элемент, отсортировать массив). тогда получим
Исходный класс — ArrayInt1
using System; namespace ArrayIntOne < class ArrayInt1 < protected int n; // длина массива protected int[] a; // массив целых чисел // пустой конструктор - нужен для дочернего класса public ArrayInt1() < >// конструктор целочисленного массива длиной N. Элементы массива имеют значения по умолчанию public ArrayInt1(int N) < n = N; a = new int[n]; >// конструктор с генератором случайных чисел от 0 до max public ArrayInt1(int N, int max) < Random rnd = new Random(); n = N; a = new int[n]; for (int i = 0; i < n; i++) a[i] = rnd.Next(max + 1); >// конструктор с генератором случайных чисел от min до max public ArrayInt1(int N, int min, int max) < Random rnd = new Random(); n = N; a = new int[n]; for (int i = 0; i < n; i++) a[i] = rnd.Next(min, max + 1); >// Вывод элементов массива с контролем их наличия public virtual void ArrayInt_Out(string info) < Console.WriteLine(info); if (!(a == null)) // число элементов >0 < foreach (int e in a) Console.Write(e.ToString() + "\t"); Console.WriteLine(); >else // число элементов = 0 Console.WriteLine("Нет элементов " + info); > // Поиск минимального элемента (min) и его номера (k) public virtual int N_min_Array(out int min) < min = a[0]; int k = 0; for (int i = 1; i < n; i++) if (a[i] < min) < min = a[i]; k = i; >return k; > // Поиск максимального элемента (max) и его номера (k) public virtual int N_max_Array(out int max) < max = a[0]; int k = 0; for (int i = 1; i < n; i++) if (a[i] >max) < max = a[i]; k = i; >return k; > // Изменить a[k] на заданный elem (нумерация с 0) public virtual void Set_Element(int k, int elem) < if (k >= 0 && k < n) a[k] = elem; >// Извлечь k-й элемент массива (нумерация с 0) public virtual int Get_Element(int k) < if (k >= 0 && k < n) return a[k]; else return Int32.MinValue; >// Пузырьковая сортировка по возрастанию(U)/убыванию(D)/без нее. public virtual void BubbleSort(char d) < int temp; switch (d) < case 'U': // по возрастанию for (int i = 0; i < n; i++) for (int j = n - 1; j >i; j--) if (a[j - 1] > a[j]) < temp = a[j]; a[j] = a[j - 1]; a[j - 1] = temp; >break; case 'D': // по убыванию for (int i = 0; i < n; i++) for (int j = n - 1; j >i; j--) if (a[j - 1] < a[j]) < temp = a[j]; a[j] = a[j - 1]; a[j - 1] = temp; >break; default: // без сортировки break; > > > >
3. Предположим, что нам нужно изменить или что-либо добавить в этот класс. Но им уже пользуются в других проектах, поэтому эти изменения сделаем в дочернем классе, который назовем ArrayIntOne.Три конструктора оставим без изменений, добавим конструктор для чтения из текстового файла.
Пусть файл данных имеет вид:
7
2
4
1
7
6
5
8
где первое число задает количество элементов массива, а далее в каждой строке по одному записываются эти элементы. Присвойте файлу имя, например, M1.txt, разместите его в папке с программой (exe-файлом). Тогда при запросе имени файла Вам будет достаточно указать его имя без расширения — M1.
Для примера также выполним перегрузку метода Get_Element(int k). Тогда получим класс ArrayIntOne, как дочерний класс от ArrayInt1:
Наследование класса — ArrayIntOne
using System; using System.IO; using System.Text; namespace ArrayIntOne < class ArrayIntOne : ArrayInt1 < public delegate bool IsEqual(int x); // делегат от int x ->bool public int Length // свойство "Число элементов массива" < get < return n; >> // конструкторы без изменений содержимого // могут быть перегружены public ArrayIntOne(int n) : base(n) < >public ArrayIntOne(int n, int max) : base(n, max) < >public ArrayIntOne(int n, int min, int max) : base(n, min, max) < >// конструктор для ввода данных из текстового файла public ArrayIntOne(string info) : base() < Console.WriteLine(info); Console.Write("Задайте имя текстового файла данных без расширения: "); string file_name = Console.ReadLine() + ".txt"; StreamReader sr; // поток для чтения try < // Чтение чисел из файла без ошибок // связывание с файлом, кодировка символов Юникода sr = new StreamReader(file_name, UTF8Encoding.Default); // чтение 0-й строки (длина массива) string t = sr.ReadLine(); n = Convert.ToInt32(t); a = new int[n]; int i = 0; // счетчик строк // чтение из файла чисел по строке в массив while ((t != null) && (i < n)) < t = sr.ReadLine(); // чтение строк a[i] = Convert.ToInt32(t); i++; >// закрытие файла для чтения sr.Close(); > catch (Exception ex) // на случай ошибок < Console.WriteLine("ОШИБКА: " + ex.Message); >> // конструктор для ввода массива с клавиатуры (если строковый параметр имеет значение "keyboard") - Автор Эд. // или из строки, в которой целые числа (элементы массива) разделены пробелами. // если в строке чисел меньше, чем длина массива, последние элементы массива получают значение по умолчанию // если в строке чисел больше, чем длина массива, последние числа строки не учитываются // если k-й элемент строки нельзя преобразовать в целое число, k-й элемент массива получает значение по умолчанию public ArrayIntOne(int N, string s) < n = N; a = new int[n]; if (s == "keyboard") < Console.WriteLine("Введите элементов целочисленного массива", n); for (int i = 0; i < n; i++) < Console.Write("a[]: ", i); a[i] = Convert.ToInt32(Console.ReadLine()); > > else < string[] numbers = s.Split(' ', StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < n; i++) < if (i < numbers.Length && Int32.TryParse(numbers[i], out int b)) a[i] = b; >> > // Для иллюстрации перегрузки метода добавлена только печать строки public override int Get_Element(int k) < Console.WriteLine("Перегруженный метод Get_Element()"); return base.Get_Element(k); >// Суммирование элементов массива public int Sum() < int sum = 0; foreach (int e in a) sum += e; return sum; >// метод находит все элементы массива удовлетворяющие условию, заданному делегатом (лямбда-выражением) // и возвращает новый экземпляр класса (массив, состоящий из этих элементов) - автор Эд. public ArrayIntOne Find_All(IsEqual fnc) < int b = 0; // число элементов, удовлетворяющих условию foreach (int i in a) if (fnc(i)) b += 1; ArrayIntOne a1 = new ArrayIntOne(b); // инициализация нового массива // заполнение нового массива по условию, задаваемому предикатом b = 0; for (int i = 0; i < n; i++) if (fnc(a[i])) < a1.Set_Element(b, a[i]); b++; >return a1; > > >
Замечу, что для чтения файла понадобились директивы
using System.IO; using System.Text;
4. В решениях задач по основам C# вы часто использовали различные алгоритмы контроля ввода целых чисел. Ранее был написан класс Restricted Integer Number (RIN) — «Ограниченное целое число», который удобно использовать в нашей тестовой программе:
Класс RIN — ограниченное целое число
NEW: Наш Чат, в котором вы можете обсудить любые вопросы, идеи, поделиться опытом или связаться с администраторами.
Реализация динамического двумерного массив как поле класса в С++
уважаемые участники сообщества! Недавно стал изучать С++. Необходимо заполнить двумерный массив по диагонали. Решил выполнить задачу путем реализации динамического двумерного массива как поле класса. Иными другими способами задачу уже решил. Хочу именно с таким алгоритмом разобраться. Компилятор выдает ошибку в 27 строке, в методе заполнения массива. Помогите разобраться в чем проблема.
#include #include #include using namespace std; class Massive < private: int** Mass; int Size; public: Massive(int Size_of_Mass) < Size = Size_of_Mass; int** Mass = new int* [Size]; for (int i = 0; i < Size; i++) < Mass[i] = new int[Size]; >> void Mass_diag(int MAX) < // Метод заполнения массива по диагонали int k = 1; // Первый элемент массива, индексы (0, 0) int z = 0; // Счетчик строк while (k > > z++; > > void show(int MAX) < for (int i = 0; i < MAX; i++) < for (int j = 0; j < MAX; j++) < cout cout > >; int main() < system("chcp 1251 >NULL"); int size; // Размер массива cout > size; Massive objA(size); objA.Mass_diag(size); objA.show(size); return 0; >
Отслеживать
47.9k 17 17 золотых знаков 56 56 серебряных знаков 100 100 бронзовых знаков
Массив как поле класса c
Здравствуйте, Visor2004, Вы писали:
V>как его проинициализировать, в конструкторе, например?
Тупо в цикле.
Но можно в списке инициализации конструктора — нулем.
Хочешь быть счастливым — будь им!
Без булдырабыз.
Re: поле класса — массив
От: | jazzer | Skype: enerjazzer |
Дата: | 23.05.13 08:55 | |
Оценка: |
Здравствуйте, Visor2004, Вы писали:
V>как его проинициализировать, в конструкторе, например?
Если речь о С++11 — как обычно:
struct A < int a[5]; A():a <> >;
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09
You will always get what you always got If you always do what you always did
Re: поле класса — массив
От: | Visor2004 | |
Дата: | 23.05.13 09:59 | |
Оценка: | -1 |
Здравствуйте, Visor2004, Вы писали:
V>как его проинициализировать, в конструкторе, например?
Хочу что-то типа такого:
class A < int array[]; A(int size) < array = new int[size]; >; >
Помните. ваш говнокод кому-то предстоит разгребать.
Re[2]: поле класса — массив
От: | LaptevVV |
Дата: | 23.05.13 10:43 |
Оценка: |
Здравствуйте, Visor2004, Вы писали:
V>Здравствуйте, Visor2004, Вы писали:
V>>как его проинициализировать, в конструкторе, например?
V>Хочу что-то типа такого:
V>
V>class A V> < V>int array[]; V> A(int size) V> < V>array = new int[size]; V> >; V>> V>
Динамический массив инициализируется нулем при создании — поставь скобочки () после квадратных.
Хочешь быть счастливым — будь им!
Без булдырабыз.
Re[2]: поле класса — массив
От: | Erop | |
Дата: | 23.05.13 14:24 | |
Оценка: | +2 |
Здравствуйте, Visor2004, Вы писали:
V>Хочу что-то типа такого:
V>
V>class A V> < V>int array[]; V> A(int size) V> < V>array = new int[size]; V> >; V>> V>
class A < std::vectorint> array; A(size_t size) : array( size ) <> >;
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно «ради красного словца». За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: поле класса — массив
От: | Erop |
Дата: | 23.05.13 14:27 |
Оценка: |
Здравствуйте, LaptevVV, Вы писали:
LVV>Динамический массив инициализируется нулем при создании — поставь скобочки () после квадратных.
А это невозможным, но принципиально описуемым массивом функций, часом не окажется.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно «ради красного словца». За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: поле класса — массив
От: | Pavel Dvorkin |
Дата: | 23.05.13 14:47 |
Оценка: |
Здравствуйте, Visor2004, Вы писали:
V>Хочу что-то типа такого:
V>
V>class A V> < V>int array[]; V> A(int size) V> < V>array = new int[size]; V> >; V>> V>
Определись с тем, что ты хочешь иметь.
Если массив — нужно указать его размер (константой), и тем самым неявно выделится память. И не надо new
class A < int array[CONST_SIZE]; A(int size) < >>;
Если нет — тогда тебе нужен указатель, под который выделишь память
class A < int *array; A(int size) < array = new int[size]; >; >
With best regards
Pavel Dvorkin
Re[4]: поле класса — массив
От: | LaptevVV |
Дата: | 23.05.13 17:43 |
Оценка: |
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, LaptevVV, Вы писали:
LVV>>Динамический массив инициализируется нулем при создании — поставь скобочки () после квадратных.
E>А это невозможным, но принципиально описуемым массивом функций, часом не окажется.
У меня до сих пор не оказывалось.
int *p = new int [n](); // -- так инициализируется --
Может, по новому стандарту это уже не массив ?
Хочешь быть счастливым — будь им!
Без булдырабыз.
Re[2]: поле класса — массив
От: | rg45 |
Дата: | 23.05.13 18:30 |
Оценка: |
Здравствуйте, Visor2004, Вы писали:
V>Здравствуйте, Visor2004, Вы писали:
V>>как его проинициализировать, в конструкторе, например?
V>Хочу что-то типа такого:
V>
V>class A V> < V>int array[]; V> A(int size) V> < V>array = new int[size]; V> >; V>> V>
И чему должно быть равно sizeof(A) по-твоему?
Re[2]: поле класса — массив
От: | robin_of_the_wood |
Дата: | 23.05.13 18:31 |
Оценка: |
Здравствуйте, Visor2004, Вы писали:
V>Хочу что-то типа такого:
V>
V>class A V> < V>int array[]; V> A(int size) V> < V>array = new int[size]; V> >; V>> V>
В таком случае sizeof для этого класса компилятору посчитать будет нелегко, так как он будет известен только в рантайме
Проектирование велосипедов для слепых жирафов
Re[3]: поле класса — массив
От: | robin_of_the_wood |
Дата: | 23.05.13 18:33 |
Оценка: |
R>И чему должно быть равно sizeof(A) по-твоему?
Проектирование велосипедов для слепых жирафов
Re[5]: поле класса — массив
От: | Erop |
Дата: | 23.05.13 20:23 |
Оценка: |
Здравствуйте, LaptevVV, Вы писали:
E>>А это невозможным, но принципиально описуемым массивом функций, часом не окажется.
Блин, теперь понял о чём ты. Так, конечно, не окажется
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно «ради красного словца». За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: поле класса — массив
От: | rg45 |
Дата: | 24.05.13 07:39 |
Оценка: |
Здравствуйте, Visor2004, Вы писали:
V>Хочу что-то типа такого:
V>
V>class A V> < V>int array[]; V> A(int size) V> < V>array = new int[size]; V> >; V>> V>
V>—
V>Помните. ваш говнокод кому-то предстоит разгребать.
Вместе с подписью выглядит устрашающе
Re[3]: поле класса — массив
От: | Visor2004 |
Дата: | 24.05.13 07:59 |
Оценка: |
Здравствуйте, rg45, Вы писали:
R>И чему должно быть равно sizeof(A) по-твоему?
размеру указателя на первый элемент массива вестимо.
Помните. ваш говнокод кому-то предстоит разгребать.
Re[3]: поле класса — массив
От: | Visor2004 |
Дата: | 24.05.13 08:02 |
Оценка: |
Здравствуйте, rg45, Вы писали:
R>Вместе с подписью выглядит устрашающе
Именно поэтому и интересуюсь как у вас принято такие вещи делать. В принципе, я так понял, что надо объявлять указатель внутри класса, а не массив.
class A < int * array; A(int size) < array = new int[size]; >; >
Помните. ваш говнокод кому-то предстоит разгребать.
Re[3]: поле класса — массив
От: | Visor2004 |
Дата: | 24.05.13 08:14 |
Оценка: |
Здравствуйте, robin_of_the_wood, Вы писали:
___>В таком случае sizeof для этого класса компилятору посчитать будет нелегко, так как он будет известен только в рантайме
исходя из документации в переменной array всегда будет указатель на первый элемент в независимости от размера массива, разве нет?
Помните. ваш говнокод кому-то предстоит разгребать.
Re[3]: поле класса — массив
От: | Visor2004 |
Дата: | 24.05.13 08:18 |
Оценка: |
Здравствуйте, Erop, Вы писали:
E>Дык
class A < E>std::vectorint> array; E> A(size_t size) : array( size ) <> E>>;
мне надо потом этот массив по указателю передавать, а я так смотрю, что получить указатель на элементы можно только в версии для С++11
Помните. ваш говнокод кому-то предстоит разгребать.
Re[4]: поле класса — массив
От: | B0FEE664 |
Дата: | 24.05.13 08:35 |
Оценка: |
Здравствуйте, Visor2004, Вы писали:
E>>Дык
class A < E>> std::vectorint> array; E>> A(size_t size) : array( size ) <> E>>>;
жеж.
V>мне надо потом этот массив по указателю передавать, а я так смотрю, что получить указатель на элементы можно только в версии для С++11
int* p = &array[0];
И каждый день — без права на ошибку.
Re[4]: поле класса — массив
От: | Vzhyk |
Дата: | 24.05.13 08:39 |
Оценка: |
On 24.05.2013 11:18, Visor2004 wrote:
> мне надо потом этот массив по указателю передавать, а я так смотрю, что
> получить указатель на элементы можно только в версии для С++11
А Страуструпа почитать, можно и первое издание?
Posted via RSDN NNTP Server 2.1 beta
Re[4]: поле класса — массив
От: | rg45 |
Дата: | 24.05.13 08:43 |
Оценка: |
Здравствуйте, Visor2004, Вы писали:
R>>Вместе с подписью выглядит устрашающе
V>Именно поэтому и интересуюсь как у вас принято такие вещи делать. В принципе, я так понял, что надо объявлять указатель внутри класса, а не массив.
Только, не забыть потом в деструкторе освободить выделенную память. И инициализацию указателя лучше выполнять в списке инициализации, а не в теле конструктора. А чтобы массив содержал не какой-то мусор, а был инициализирован нулями, можно использовать value-initialization (пустые скобочки):
class A < int * array; A(int size) : array(new int[size]()) < >~A() < delete[] array; >>
А еще лучше, как уже посоветовали выше, не делать ненужную работу, не создавать почву для ненужных ошибок, а использовать std::vector.
Re[5]: поле класса — массив
От: | rg45 | |
Дата: | 24.05.13 08:57 | |
Оценка: | 9 (2) |
Здравствуйте, rg45, Вы писали:
R>>>Вместе с подписью выглядит устрашающе
V>>Именно поэтому и интересуюсь как у вас принято такие вещи делать. В принципе, я так понял, что надо объявлять указатель внутри класса, а не массив.
R>Только, не забыть потом в деструкторе освободить выделенную память. И инициализацию указателя лучше выполнять в списке инициализации, а не в теле конструктора. А чтобы массив содержал не какой-то мусор, а был инициализирован нулями, можно использовать value-initialization (пустые скобочки):
R>
R>class A R> < R>int * array; R> A(int size) R> : array(new int[size]()) R> < R>> R> ~A() R> < R>delete[] array; R> > R>>; R>
R>А еще лучше, как уже посоветовали выше, не делать ненужную работу, не создавать почву для ненужных ошибок, а использовать std::vector.
Да, я упустил еще такой важный момент, как копирование объекта! В таком виде класс оставлять нельзя, поскольку копирование, реализованное по умолчанию компилятором, будет приводить к неопределенному поведению (многократное удаление одного и того же объекта). Копирование в этом случае необходимо либо запретить, либо реализовать по уму. При этом не забыть, что помимо копирующего конструктора существует еще копирующий оператор присваивания. И сделать это нужно будет грамотно, обеспечив безопасность с точки зрения исключений. А в C++11 помимо копирования объектов есть еще перемещение. В общем, аргументов в пользу использования стандартных контейнеров не мало.
Re[6]: поле класса — массив
От: | Visor2004 |
Дата: | 24.05.13 09:01 |
Оценка: |
Здравствуйте, rg45, Вы писали:
R>Да, я упустил еще такой важный момент, как копирование объекта! В таком виде класс оставлять нельзя, поскольку копирование, реализованное по умолчанию компилятором, будет приводить к неопределенному поведению (многократное удаление одного и того же объекта). Копирование в этом случае необходимо либо запретить, либо реализовать по уму. При этом не забыть, что помимо копирующего конструктора существует еще копирующий оператор присваивания. И сделать это нужно будет грамотно, обеспечив безопасность с точки зрения исключений. А в C++11 помимо копирования объектов есть еще перемещение. В общем, аргументов в пользу использования стандартных контейнеров не мало.
Помните. ваш говнокод кому-то предстоит разгребать.
Re[4]: поле класса — массив
От: | Erop | |
Дата: | 24.05.13 09:25 | |
Оценка: | +1 |
Здравствуйте, Visor2004, Вы писали:
V>мне надо потом этот массив по указателю передавать, а я так смотрю, что получить указатель на элементы можно только в версии для С++11
&array[0] для непустого массива
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно «ради красного словца». За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: поле класса — массив
От: | Erop |
Дата: | 24.05.13 09:36 |
Оценка: |
Здравствуйте, Visor2004, Вы писали:
V>исходя из документации в переменной array всегда будет указатель на первый элемент в независимости от размера массива, разве нет?
Исходя из документации так если и можно писать в некоторых реализациях С++, то означает это совсем другое.
Тебе, скорее всего, с этим лучше не заморачиваться и для начала освоить стандартный путь, через std::vector. Но понимать, что такое бывает всё-таки стоит.
Аллокация/освобождение блока памяти — довольно дорогая операция, поэтому, если использование этого твоего A таково, что он сам всегда аллокируется по new, то получается, что каждый new A порождает две аллокации — под сам A и под лежащий внутри его массив.
В принципе часто возникает соблазн как-то запихать эти два блока памяти в один. Тогда пишут специальный хитрый метод аллокации экземпляров A, ну, например, это будет статический метод самого A: A* A::AllocateNew( int size );
И он там, внутри всё делает правильно.
Вот для поддержки такой техники некоторые компиляторы и позволяют писать в конце объекта этакий пустой массив (с пустыми []), это просто обозначает указатель сразу за конец объекта, или что-то вроде того, а функция аллокации так хитро всё располагает в памяти, что сразу за концом объекта идёт его массив. В результате
1) Не надо хранить лишний указатель, адрес массива вычисляется по смещению относительно this
2) Не надо двух алллокаций вместо одной
3) Код становится более запутанным и непонятным.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно «ради красного словца». За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: поле класса — массив
От: | robin_of_the_wood |
Дата: | 24.05.13 10:57 |
Оценка: |
Здравствуйте, Visor2004, Вы писали:
___>>В таком случае sizeof для этого класса компилятору посчитать будет нелегко, так как он будет известен только в рантайме
V>исходя из документации в переменной array всегда будет указатель на первый элемент в независимости от размера массива, разве нет?
Посмотрите в отладчике дамп памяти, занимемой обьектом Вашего класса.
Для удобства инициализируйте массив чем-то вроде 0x11111111, 0x22222222, итд. Все увидите.
Проектирование велосипедов для слепых жирафов
Re[4]: поле класса — массив
От: | rg45 |
Дата: | 24.05.13 12:18 |
Оценка: |
Здравствуйте, Visor2004, Вы писали:
___>>В таком случае sizeof для этого класса компилятору посчитать будет нелегко, так как он будет известен только в рантайме
V>исходя из документации в переменной array всегда будет указатель на первый элемент в независимости от размера массива, разве нет?
Если переменная объявлена как int* array, то да, а если как int array[], то нет — это будет массив, неизвестного размера, но, все же массив. Вообще, концепции массива и указателя традиционно вызывают путаницу у тех, кто только начинает знакомство с C/C++. Указатель и массив очень похожи при использовании, поэтому их легко спутать. Кроме того, массив может быть приведен к указателю неявно, что только усиливает неразбериху.
Основное отличие массива и указателя состоит в представлении данных в памяти. Массив (как можно догадаться из названия) — это непрерывная последовательность однотипных объектов, расположенных в непрерывной области памяти друг за другом. Указатель — это объект, хранящий адрес другого объекта. Важной особенностью является то, что указатели одного и того же типа (да даже один и тот же указатель) могут указывать как на одиночный объект, так и на какой либо (не обязательно первый) элемент массива — с точки зрения компилятора такие указатели абсолютно равнозначны и ответственность за корректное их использование лежит на программисте. Ничто не мешает программисту использовать указатель на одиночный объект, как указатель на элемент массива — например, применять к нему операцию индексирования или адресную арифметику, и это не вызовет ошибок времени компиляции. Но это приведет более страшным последствиям — неопределенному поведения программы во время ее выполнения — это может быть что угодно — от аварийного завершения до форматирования диска C: (как часто шутят в таких случаях). Поэтому с указателями нужно обращаться аккуратно, а лучше не использовать их вообще без осознанной необходимости — использовать где это возможно умные указатели и обертки.