Почему конструктор вызывает конструктор странные результаты? - PullRequest
0 голосов
/ 01 декабря 2018

Я просто тестирую код, показанный ниже (обучение oop в c++).

(система: linux, компилятор gcc с -std=c++11)

#include <iostream>

class Point {
  private:
    double x, y;

  public:
    static unsigned int pCount;

    // constructor1 with no initial arguments
    Point() {
      x = 0.0f;
      y = 0.0f;
      std::cout << "Point()" << " x = " << x << " y = " << y
          << " point no: " << ++pCount << std::endl;
    }

    /*
    // constructor1 alternative: calling another constructor
    Point() {
      Point(0.0f, 0.0f);
      std::cout << "Point()" << std::endl;
    }
    */

    // constructor2 with initial arguments
    Point(double cx, double cy) {
      x = cx;
      y = cy;
      std::cout << "Point(double, double)" << " x = " << x << " y = " << y
          << " point no: " << ++pCount << std::endl;
    }

    void Show() {
      std::cout << "Show()" << " x = " << x << " y = " << y << std::endl;
    }

    virtual ~Point() {
      std::cout << "~Point()" << " x = " << x << " y = " << y 
          << " point no: " << pCount-- << std::endl;
    }
};

unsigned int Point::pCount = 0;

int main(int argc, char *argv[]) {
  Point p1(2.5, 7.6);
  Point p2;

  p2.Show();
  p1.Show();

  return (0);
}

Код выше создает вывод в виде:

Point(double, double) x = 2.5 y = 7.6 point no: 1
Point() x = 0 y = 0 point no: 2
Show() x = 0 y = 0
Show() x = 2.5 y = 7.6
~Point() x = 0 y = 0 point no: 2
~Point() x = 2.5 y = 7.6 point no: 1

Однако, когда я закомментирую constructor1 и раскомментируем constructor1 alternative, созданный вывод становится немного странным, как показано ниже:

Point(double, double) x = 2.5 y = 7.6 point no: 1
Point(double, double) x = 0 y = 0 point no: 2
~Point() x = 0 y = 0 point no: 2
Point()
Show() x = 4.64944e-310 y = 9.88131e-324
Show() x = 2.5 y = 7.6
~Point() x = 4.64944e-310 y = 9.88131e-324 point no: 1
~Point() x = 2.5 y = 7.6 point no: 0

Я думаю, что в последнем случае (constructor1 alternative) создается временный объект, а затем его указатель передается в p2.Во всяком случае, пока, все хорошо ... Но я застрял со значениями, присвоенными переменным x & y: первый показывает x = 0, y = 0, как и ожидалось;однако последний выплевывает x = 4.63813e-310, y = 9.88131e-324, хотя значения очень близки к нулю, мне все равно это кажется странным.

Почему в последнем случае не назначаются точные значения " zero "?

1 Ответ

0 голосов
/ 01 декабря 2018

Я думаю, что в последнем случае (constructor1 alternative) создается временный объект, а затем его указатель передается в p2

Вы правы, временный объект действительно создан, но он разрушен сразу после строительства.Возможно, вы захотите использовать конструктор делегата следующим образом:

Point() : Point(0.0, 0.0) {}

Это вызовет конструктор с двумя двойными аргументами, и оба члена данных будут инициализированы.Обратите внимание, что «странное» поведение, на которое вы ссылались, - не что иное, как неинициализированные данные - члены данных содержат значения мусора, так как они не были инициализированы.

Как примечание (я понимаю, что вы сказали, чтоо изучении ООП, так что не принимайте это замечание слишком серьезно): мне кажется, что два члена координатных данных вашего класса Point могут изменяться независимо друг от друга.Следовательно, ваш класс не управляет инвариантом - в этом случае вы можете захотеть упростить тип до

struct Point { double x = 0.0; double y = 0.0; };

, что позволяет строить по умолчанию

Point p; // both x and y are 0.0 now

, а такжеинициализация агрегата

Point p{3.14, 42.0};

Дополнительные функции, являющиеся частью интерфейса вашего класса (печать, расстояние до другой точки и т. д.), удобно определять в свободных функциях.

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