C ++ указатель на объекты - PullRequest
22 голосов
/ 07 июня 2010

В C ++ вы всегда инициализируете указатель на объект ключевым словом new?

Или вы тоже можете это иметь:

MyClass *myclass;

myclass->DoSomething();

Я думал, что это указатель, выделенный в стеке, а не в куче, но поскольку объекты обычно выделяются в куче, я думаю, что моя теория, вероятно, ошибочна ??

Пожалуйста, совет.

Ответы [ 7 ]

35 голосов
/ 07 июня 2010

Нет, вы можете иметь указатели для размещения выделенных объектов:

MyClass *myclass;
MyClass c;
myclass = & c;
myclass->DoSomething();

Это, конечно, часто встречается при использовании указателей в качестве параметров функции:

void f( MyClass * p ) {
    p->DoSomething();
}

int main() {
    MyClass c;
    f( & c );
}

Так или иначе, указатель всегда должен быть инициализирован. Ваш код:

MyClass *myclass;
myclass->DoSomething();

приводит к этому ужасному состоянию, неопределенное поведение .

23 голосов
/ 07 июня 2010

Нет, вы не можете этого сделать, MyClass *myclass определит указатель (память для указателя выделяется в стеке), который указывает на случайное место в памяти. Попытка использовать этот указатель приведет к неопределенному поведению.

В C ++ вы можете создавать объекты в стеке или в куче следующим образом:

MyClass myClass;
myClass.DoSomething();

Выше будет размещаться myClass в стеке (я думаю, что этого термина нет в стандарте, но я использую его для ясности). Память, выделенная для объекта, автоматически освобождается, когда переменная myClass выходит из области видимости.

Другим способом выделения памяти является new. В этом случае вы должны позаботиться об освобождении памяти, выполнив delete самостоятельно.

MyClass* p = new MyClass();
p->DoSomething();
delete p;

Запомните часть delete, иначе произойдет утечка памяти.

Я всегда предпочитаю использовать объекты, выделенные в стеке, когда это возможно, поскольку мне не нужно беспокоиться об управлении памятью.

10 голосов
/ 07 июня 2010

, если вы хотите, чтобы объект находился в стеке, попробуйте это:

2 голосов
/ 14 декабря 2014

Сначала я должен сказать, что ваш код,

MyClass *myclass;
myclass->DoSomething();

вызовет неопределенное поведение . Поскольку указатель «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 будет делать это в куче.

1 голос
/ 15 июня 2014

Если вы определили метод внутри вашего класса как статический, это действительно возможно.

    class myClass
    {
    public:
        static void saySomething()
        {
            std::cout << "This is a static method!" << std::endl;
        }
    }; 

А из main вы объявляете указатель и пытаетесь вызвать статический метод.

    myClass * pmyClass;
    pmyClass->saySomething();

/*    
Output:
This is a static method!
*/

Это прекрасно работает, потому что статические методы не принадлежат конкретному экземпляру класса и не размещаются как часть какого-либо экземпляра класса.

Подробнее о статических методах здесь: http://en.wikipedia.org/wiki/Static_method#Static_methods

1 голос
/ 26 декабря 2013

, если вы хотите получить доступ к методу:

1) при использовании объекта класса:

Myclass myclass;
myclass.DoSomething();

2) при использовании указателя на объект класса:

Myclass *myclass=&abc;
myclass->DoSomething();
0 голосов
/ 07 января 2018

Простое решение для наведения указателя на объект

Демо онлайн

class myClass
{
  public:
  void sayHello () {
    cout << "Hello";
  }
};

int main ()
{
  myClass* myPointer;
  myClass myObject = myClass(* myPointer); // Cast pointer to object
  myObject.sayHello();

  return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...