Я пытаюсь осмыслить указатели / разрушение и тому подобное. Я использую приведенный ниже код, чтобы использовать указатель для x вместо стандартного int; однако, если я использую список инициализации в конструкторе, он не будет компилироваться, а если я просто назначу его обычным образом в методе конструктора, он будет работать нормально.

#include<iostream>
using namespace std;

class Point
{
private:
    int *x;
    int y;
public:
    Point(int x1, int y1):*x(x1),y(y1) {}

    // Copy constructor
    Point(const Point &p2) {*x = *p2.x; y = p2.y; }
   // ~Point(){delete x;}

    int getX()            {  return *x; }
    int getY()            {  return y; }
    void setX(int x1){*x=x1;}
};

int main()
{
    Point p1(10, 15); // Normal constructor is called here
    Point p2 = p1; // Copy constructor is called here
    p2.setX(35);

    // Let us access values assigned by constructors
    cout << "p1.x = " << p1.getX() << ", p1.y = " << p1.getY();
    cout << "\np2.x = " << p2.getX() << ", p2.y = " << p2.getY();

    return 0;
}

У меня также есть второй вопрос, который является правильным способом инициировать указатель int следующим образом:

int *p = new int;
*p = 3;

Или вот так:

int *p;
*p = 3;

Я заметил, что если я назначаю nullptr или 0 и пытаюсь отобразить указатель, он ничего не выводит, есть ли для этого причина? например:

int *p = 0;
*p = 3;
cout << *p;
0
Wolf 30 Дек 2015 в 21:15

2 ответа

Лучший ответ

Point(int x1, int y1):*x(x1),y(y1) {} недопустимый синтаксис. Вы можете инициализировать только элементы в списках инициализации, а *x не является участником. Кстати, даже если бы компилятор разрешил это, он произвел бы неопределенное поведение - вы бы разыменовали неинициализированный указатель.

Один из способов (по крайней мере, синтаксически правильный и не приводящий к неопределенному поведению в этой самой строке) был бы

 Point(int x1, int y1): x(new int(x1)), y(y1) {}

Второй вопрос фактически такой же, как и первый. Во втором примере вы будете обращаться к указателю без его предварительной инициализации, что приведет к неопределенному поведению.

3
SergeyA 30 Дек 2015 в 18:18

Когда конструктор вызывается Point(int x1, int y1):*x(x1), ваш x-адрес неверен (не назначен), потому что он не был инициализирован, поэтому он может указывать куда угодно в вашей оперативной памяти.

Выполняя *x(x1), если это разрешено, вы:

  • либо испортить вашу текущую память
  • либо segfault
0
Pierre Emmanuel Lallemant 30 Дек 2015 в 18:19