Указатель С++ на объекты
В С++ вы всегда инициализируете указатель на объект с ключевым словом new
?
Или вы тоже можете это сделать:
MyClass *myclass;
myclass->DoSomething();
Я думал, что это был указатель, выделенный в стеке вместо кучи, но поскольку объекты обычно выделены кучей, я думаю, что моя теория, вероятно, ошибочна??
Пожалуйста, совет.
Ответы
Ответ 1
Нет, у вас могут быть указатели для размещения выделенных объектов:
MyClass *myclass;
MyClass c;
myclass = & c;
myclass->DoSomething();
Это, конечно, распространено при использовании указателей в качестве параметров функции:
void f( MyClass * p ) {
p->DoSomething();
}
int main() {
MyClass c;
f( & c );
}
Так или иначе, указатель всегда должен быть инициализирован. Ваш код:
MyClass *myclass;
myclass->DoSomething();
приводит к этому страшному состоянию, undefined поведение.
Ответ 2
Нет, вы не можете этого сделать, MyClass *myclass
определит указатель (память для указателя выделена в стеке), который указывает на случайную ячейку памяти. Попытка использовать этот указатель вызовет поведение undefined.
В С++ вы можете создавать объекты на стеке или в куче, например:
MyClass myClass;
myClass.DoSomething();
Выше будет выделяться myClass на стеке (термин не существует в стандарте, я думаю, но я использую для ясности). Память, выделенная для объекта, автоматически освобождается, когда переменная myClass
выходит за пределы области видимости.
Другой способ выделения памяти - сделать new
. В этом случае вам нужно позаботиться о том, чтобы освободить память, выполнив delete
самостоятельно.
MyClass* p = new MyClass();
p->DoSomething();
delete p;
Вспомните часть delete
, иначе произойдет утечка памяти.
Я всегда предпочитаю использовать выделенные объекты стека, когда это возможно, поскольку мне не нужно беспокоиться об управлении памятью.
Ответ 3
если вы хотите объект в стеке, попробуйте следующее:
MyClass myclass;
myclass.DoSomething();
Если вам нужен указатель на этот объект:
MyClass* myclassptr = &myclass;
myclassptr->DoSomething();
Ответ 4
если вы хотите получить доступ к методу:
1) при использовании объекта класса:
Myclass myclass;
myclass.DoSomething();
2) при использовании указателя на объект класса:
Myclass *myclass=&abc;
myclass->DoSomething();
Ответ 5
Если вы определили метод внутри вашего класса как статический, это действительно возможно.
class myClass
{
public:
static void saySomething()
{
std::cout << "This is a static method!" << std::endl;
}
};
И из основного вы объявляете указатель и пытаетесь вызвать статический метод.
myClass * pmyClass;
pmyClass->saySomething();
/*
Output:
This is a static method!
*/
Это отлично работает, потому что статические методы не относятся к определенному экземпляру класса, и они не выделяются как часть любого экземпляра класса.
Подробнее о статических методах читайте здесь: http://en.wikipedia.org/wiki/Static_method#Static_methods
Ответ 6
Сначала мне нужно сказать, что ваш код,
MyClass *myclass;
myclass->DoSomething();
приведет к undefined поведение.
Поскольку указатель "myclass" не указывает на какие-либо объекты типа "MyClass".
Здесь у меня есть три предложения для вас: -
вариант 1: -. Вы можете просто объявить и использовать объект типа MyClass в стеке, как показано ниже.
MyClass myclass; //allocates memory for the object "myclass", on the stack.
myclass.DoSomething();
вариант 2: - Используя новый оператор.
MyClass *myclass = new MyClass();
Здесь три вещи.
i) Выделяет память для объекта типа "MyClass" в куче.
ii) Выделяет память для указателя типа MyClass "myclass" в стеке.
iii) указатель "myclass" указывает на адрес памяти объекта типа "MyClass" в куче
Теперь вы можете использовать указатель для доступа к функциям-членам объекта после разыменования указателя с помощью "- > "
myclass->DoSomething();
Но вы должны освободить память, выделенную для объекта типа "MyClass" в куче, перед возвратом из области действия, если вы не хотите, чтобы она существовала. В противном случае это приведет к утечке памяти!
delete myclass; // free the memory pointed by the pointer "myclass"
вариант 3: - вы также можете сделать, как показано ниже.
MyClass myclass; // allocates memory for the "MyClass" type object on the stack.
MyClass *myclassPtr; // allocates memory for the "MyClass" type pointer on the stack.
myclassPtr = &myclass; // "myclassPtr" pointer points to the momory address of myclass object.
Теперь указатель и объект находятся в стеке.
Теперь вы не можете вернуть этот указатель к внешней стороне текущей области, потому что освобожденная память указателя и объекта будет освобождена при выходе за пределы области.
Итак, как итог, опции 1 и 3 будут выделять объект в стеке, а только вариант 2 сделает это в куче.
Ответ 7
Простое решение для указателя на объект
Демо-версия
class myClass
{
public:
void sayHello () {
cout << "Hello";
}
};
int main ()
{
myClass* myPointer;
myClass myObject = myClass(* myPointer); // Cast pointer to object
myObject.sayHello();
return 0;
}