Я родом из Java
фон, и я недавно начал учиться Qt
с C++
, Во время кодирования у меня возникли некоторые сомнения относительно создания объектов и объявления членов:
Предположим, у меня есть класс, объявленный следующим образом:
ClassA.h:
class ClassA {
private:
MyObject myObj;
QString *declaredArray;
QSharedPointer<MyObject> obj;
public:
void setInfo();
}
ClassA.cpp
void ClassA::setInfo() {
declaredArray = new QString[5];
obj = QSharedPointer<MyObject>(new MyObject, doDeleteLater);
}
Что случилось в шапке где MyObject myObj;
был объявлен? Был объект типа MyObject
созданный в стеке и назначенный переменной myObj
используя конструктор, который не принимает аргументов? Или только пустая переменная, подготовленная для хранения MyObject
объект был объявлен?
В ClassA.cpp
как бы назначить новый объект, созданный в стеке myObj
переменная?
declaredArray это массив int
S, созданный в куче, я должен добавить деструктор с delete declaredArray;
избежать утечек памяти?
Что случилось в шапке где QSharedPointer<MyObject> obj;
был объявлен? Был пустой указатель на MyObject
создан? Является ли назначение в ClassA.cpp
(obj = QSharedPointer<MyObject>(new MyObject, doDeleteLater);
) правильный?
Там будет место для myObj
(размером MyObject
) где бы ClassA
выделяется (если ClassA
выделяется в стеке, место для myObj
будет в стеке).
Если применимый конструктор по умолчанию существует для MyObject
, и либо:
ClassA (): myObj (), declaredArray (NULL), obj (NULL) {}
… затем myObj
будет инициализирован к значению по умолчанию (MyObject()
).
Также обратите внимание, что любая выделенная куча память, которую вы создаете с new
должны быть освобождены с delete
на уничтожение. Следовательно, у вас также должен быть деструктор:
~ClassA() {
if (delcaredArray != NULL) {
delete[] declaredArray;
}
}
Благодаря RAII вам не нужно будет уничтожать myObj
а также obj
если явно инициализировано в ClassA
конструктор. Если это не так, то вам необходимо явно уничтожить их (например, в случае общего указателя уменьшить счетчик).
Чтобы ответить на другие ваши вопросы явно:
Что произошло в шапке, где MyObject myObj; был объявлен? Был ли объект типа MyObject создан в стеке и назначен переменной myObj с помощью конструктора, который не принимает аргументов? Или была объявлена только пустая переменная, подготовленная для хранения объекта MyObject?
myObj
будет построен по умолчанию (создан с помощью конструктора, который не принимает аргументов), если конструктор по умолчанию существует и был создан (неявно или явно).
В ClassA.cpp, как мне назначить новый объект, созданный в стеке, переменной myObj?
Если myObj
был действительным, то myObj = MyObject(...);
(без new
ключевое слово) будет достаточно. Обратите внимание, что это будет вызывать operator=()
(оператор присваивания) на myObj
, так myObj
должно быть уже определено для того, чтобы это было полностью определенное поведение. Если он уже построен по умолчанию, то myObj = MyObject(...);
Это хорошо.
Заявленный массив — это массив целых чисел, созданных в куче, если я добавлю деструктор с удаленным объявлением. избежать утечек памяти?
Да, вы должны, как показано выше.
Что произошло в шапке, где QSharedPointer obj; был объявлен? Был ли создан пустой указатель на MyObject? Правильно ли назначено в ClassA.cpp (obj = QSharedPointer (new MyObject, doDeleteLater);)?
документация для QSharedPointer показывает, что его конструктор по умолчанию является QSharedPointer
указывая на NULL
, Если у вас есть конструктор по умолчанию, который соответствующим образом вызывает конструктор по умолчанию для членов, то все будет в порядке.
Правильно построенный (например, построенный по умолчанию или не по умолчанию, но инициализированный) QSharedPointer
можно назначить с помощью оператора присваивания, как вы показали: (obj = QShardPointer<MyObject>(new MyObject))
,