Люди, подскажите:
создаю объект своего класса MyClass, который в качестве переменных-членов имеет объекты других моих классов, а также указатели на объекты моих классов, которые(указатели) используются для динамического выделения памяти под массивы этих объектов.
Назрела необходимость создавать произвольное число объектов класса MyClass и соответственно их нужно где-то хранить.
пробовал их хранить в массиве CArray, но он не принимает в качестве аргументов объекты MyClass уже проинициализированные
CArray<MyClass, MyClass> m_Array;
...................
MyClass myclass;
myclass.Init(10,10); <- выделяет память под массивы объектов переменных членов объекта класса MyClass
m_Sheet.Add(sheet); <- ругается "No copy constructor available for class 'MyClass'"
, т.е. принимает только вновь созданные
MyClass myclass;
m_Sheet.Add(sheet); <- все ок
что это за "конструктор копирования" и как мне решить проблему хранения этих объектов при условии, что хранимый объект может менять свои размеры, т.е. динамически выделять блоки памяти и удалять их?
Не совсем понятна ситуация, тем более что код видимо строками из рахных мест выдергивался. Могу ответить на последнюю часть вопроса.
Конструктор копирования это конструктор, который вызывается когда создаваемый объект инициализируется существующим объектом того же класса.
Например:
class CMyClass
{
...
CMyClass(const CMyClass&)
...
}
CMyClass a;
CMyClass b(a);
CMyClass c = a;
Здесь во всех трех случаях вызывается конструктор копирования.
Он же используется при передаче объекта в функцию по значению.
Если конструктор явно не определен, создается конструктор копирования по умолчанию, который просто побитово отражает состояние одного объекта на другой. Для простых объектов этого бывает достаточно, но уже в случае когда объект содержит указатели могут возникать ошибки (рантайм, не компиляции).
Что же касается хранения объектов, изменяющих размеры, то размеры-то как раз и не меняются. Грубо говоря, твой объект внутри своего "тела" хранит только указатели, которые всегда имеют фиксированный размер. Те самые массивы объектов, на которые они указывают, хранятся в куче и никакого отношения к объекту не имеют.
Вот, помог чем мог. Если было бы приведено больше кода, возможно сказал бы что-то более конкретное.
Здравствуйте Сергей, Вы писали:
С>Люди, подскажите: С>создаю объект своего класса MyClass, который в качестве переменных-членов имеет объекты других моих классов, а также указатели на объекты моих классов, которые(указатели) используются для динамического выделения памяти под массивы этих объектов. С>Назрела необходимость создавать произвольное число объектов класса MyClass и соответственно их нужно где-то хранить. С>пробовал их хранить в массиве CArray, но он не принимает в качестве аргументов объекты MyClass уже проинициализированные С>
С> CArray<MyClass, MyClass> m_Array;
С> ...................
С> MyClass myclass;
С> myclass.Init(10,10); <- выделяет память под массивы объектов переменных членов объекта класса MyClass
С> m_Sheet.Add(sheet); <- ругается "No copy constructor available for class 'MyClass'"
С>
С>
С>, т.е. принимает только вновь созданные С>
С> MyClass myclass;
С> m_Sheet.Add(sheet); <- все ок
С>
С>что это за "конструктор копирования" и как мне решить проблему хранения этих объектов при условии, что хранимый объект может менять свои размеры, т.е. динамически выделять блоки памяти и удалять их?
Здравствуйте Сергей, Вы писали:
С>Люди, подскажите: С>создаю объект своего класса MyClass, который в качестве переменных-членов имеет объекты других моих классов, а также указатели на объекты моих классов, которые(указатели) используются для динамического выделения памяти под массивы этих объектов. С>Назрела необходимость создавать произвольное число объектов класса MyClass и соответственно их нужно где-то хранить. С>пробовал их хранить в массиве CArray, но он не принимает в качестве аргументов объекты MyClass уже проинициализированные
CArray<MyClass, MyClass> m_Array;
...................
MyClass myclass;
myclass.Init(10,10); <- выделяет память под массивы объектов переменных членов объекта класса MyClass
m_Sheet.Add(sheet); <- ругается "No copy constructor available for class 'MyClass'"
На самом деле это не выход. Возможно эту локульную проблему удастся обойти, но вообще ситуация ненормальная и она точно вылезет где-то еще. Лучше разобраться с ошибко компиляции здесь, чем потом ловить ошибки выполнения.
Здравствуйте Karamat, Вы писали:
K>Здравствуйте Сергей, Вы писали:
С>>Люди, подскажите: С>>создаю объект своего класса MyClass, который в качестве переменных-членов имеет объекты других моих классов, а также указатели на объекты моих классов, которые(указатели) используются для динамического выделения памяти под массивы этих объектов. С>>Назрела необходимость создавать произвольное число объектов класса MyClass и соответственно их нужно где-то хранить. С>>пробовал их хранить в массиве CArray, но он не принимает в качестве аргументов объекты MyClass уже проинициализированные K>
K> CArray<MyClass, MyClass> m_Array;
K> ...................
K> MyClass myclass;
K> myclass.Init(10,10); <- выделяет память под массивы объектов переменных членов объекта класса MyClass
K> m_Sheet.Add(sheet); <- ругается "No copy constructor available for class 'MyClass'"
K>
K>
Здравствуйте Vyacheslav Koltovich, Вы писали:
VK>Не совсем понятна ситуация, тем более что код видимо строками из рахных мест выдергивался. Могу ответить на последнюю часть вопроса.
уточняю ситуацию:
class ChildClass
{
int *p_int;
public:
ChildClass() { p_int = NULL; };
~ChildClass() { if(p_int != NULL) delete [] p_int; };
void SetData(int number)
{
p_int = new int[number];
};
}
class MyClass
{
ChildClass m_child;
int *p_int;
public:
MyClass() { p_int = NULL; };
~MyClass{} { if(p_int != NULL) delete [] p_int; };
void Init(int i, int j)
{
m_child.SetData(i);
p_int = new int[j];
};
}
class CMyApp : public CWinApp
{
.......
CArray<MyClass, MyClass> m_Array;
void Init();
..............
}
void CMyApp::Init()
{
MyClass myclass;
myclass.Init(10,10);
m_Array.Add(myclass); <- ошибка, если не вызывать myclass.Init() ошибки нет
}
это упрощенный вариант в плане количества переменных- и функций-членов у классов ChildClass и MyClass, но сути это не меняет
...
С>class MyClass
С>{
...
С>public:
С> MyClass() { p_int = NULL; }; //<-- лишняя точка с запятой (Vi2)
С> ~MyClass{} { if(p_int != NULL) delete [] p_int; }; //<-- лишняя точка с запятой (Vi2)
// ~MyClass() //<-- деструктор так определяется (Vi2)
С> void Init(int i, int j)
С> {
С> m_child.SetData(i);
С> p_int = new int[j];
С> }; //<-- лишняя точка с запятой (Vi2)
С>} //<-- нет точки с запятой (Vi2)
...
С>это упрощенный вариант в плане количества переменных- и функций-членов у классов ChildClass и MyClass, но сути это не меняет
Наверное, слишком упрощённый вариант. У меня после переделки синтаксических ошибок — всё скомпилировалось
Компилятору без разницы — вызываешь ты какую-то функцию перед ошибочно компилируемой строкой или нет.
С> myclass.Init(10,10);
С> m_Array.Add(myclass); <- если здесь ошибка
С>// myclass.Init(10,10);
С> m_Array.Add(myclass); <- то здесь она также будет!
Здравствуйте Vi2, Вы писали:
Vi2>Здравствуйте Сергей, Вы писали:
Vi2>
Vi2>...
С>>class MyClass
С>>{
Vi2>...
С>>public:
С>> MyClass() { p_int = NULL; }; //<-- лишняя точка с запятой (Vi2)
С>> ~MyClass{} { if(p_int != NULL) delete [] p_int; }; //<-- лишняя точка с запятой (Vi2)
Vi2>// ~MyClass() //<-- деструктор так определяется (Vi2)
С>> void Init(int i, int j)
С>> {
С>> m_child.SetData(i);
С>> p_int = new int[j];
С>> }; //<-- лишняя точка с запятой (Vi2)
С>>} //<-- нет точки с запятой (Vi2)
Vi2>...
Vi2>
С>>это упрощенный вариант в плане количества переменных- и функций-членов у классов ChildClass и MyClass, но сути это не меняет
Vi2>Наверное, слишком упрощённый вариант. У меня после переделки синтаксических ошибок — всё скомпилировалось Vi2>Компилятору без разницы — вызываешь ты какую-то функцию перед ошибочно компилируемой строкой или нет. Vi2>
С>> myclass.Init(10,10);
С>> m_Array.Add(myclass); <- если здесь ошибка
С>>// myclass.Init(10,10);
С>> m_Array.Add(myclass); <- то здесь она также будет!
Vi2>
ошибок я понаделал конечно много, действительно я их исправил и все скомпилировалось, но зато прога вылетает при добавлении первого элемента в массив
template<class TYPE, class ARG_TYPE>
AFX_INLINE int CArray<TYPE, ARG_TYPE>::Add(ARG_TYPE newElement)
{ int nIndex = m_nSize;
SetAtGrow(nIndex, newElement);
return nIndex; } <- на вот этой строке
Здравствуйте Сергей, Вы писали:
С>ошибок я понаделал конечно много, действительно я их исправил и все скомпилировалось, но зато прога вылетает при добавлении первого элемента в массив
С>template<class TYPE, class ARG_TYPE>
С>AFX_INLINE int CArray<TYPE, ARG_TYPE>::Add(ARG_TYPE newElement)
С> { int nIndex = m_nSize;
С> SetAtGrow(nIndex, newElement);
С> return nIndex; } <- на вот этой строке
Что тут добавить — CArray просто требует конструктора копирования для классов с нетривиальными данными. Вот и сделай его. И почитай сообщение от Vyacheslav Koltovich.
Здравствуйте Vi2, Вы писали:
Vi2>Что тут добавить — CArray просто требует конструктора копирования для классов с нетривиальными данными. Вот и сделай его. И почитай сообщение от Vyacheslav Koltovich.
убираю из объявления и реализации класса(причем только из того, который храню в массиве, но не в тех которые в свою очередь содержаться в нем в качестве переменных-членов — в них как раз таки оставляю) конструктор и деструктор и ошибка пропадает, т.е. добавление элементов в массив происходит без проблем
Здравствуйте Сергей, Вы писали:
С>Здравствуйте Karamat, Вы писали:
С> K>>Попробуйте использовать массив указателей: K>>Не забудте их удалить после использования
С>с массивом указателей этой проблемы вроде-бы не возникает
Ошибка нашлась!!!
Всем большое спасибо за то, что помогли, без Ваших ответов я бы искал её гораздо дольше!!!