Массив как поле класса c
Перейти к содержимому

Массив как поле класса c

Массив как поле класса 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: (как часто шутят в таких случаях). Поэтому с указателями нужно обращаться аккуратно, а лучше не использовать их вообще без осознанной необходимости — использовать где это возможно умные указатели и обертки.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *