Указатель С++ на объекты

В С++ вы всегда инициализируете указатель на объект с ключевым словом 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;
}