@Mr_Epic
Web программист

Как задать свойство класса экземпляром другого класса, если его значения не известны при инициализации?

Есть класс вот такие примитивные классы:
// Point.h
class Point
{
    public:
        Point(double x, double y);
        double x_coord;
        double y_coord;
};
// Square.h
class Square
{
    public:
        Point center_pt;
        Square(double x, double y, double size);
};

// Square.cpp
Square::Square(double x, double y, double size)
{
    center_pt = *new Point(x-size/2, y-size/2);
}


Возникает ошибка:
error: no matching function for call to 'Point::Point()'

Как я понимаю компилятор хочет определить переменную center_pt с помощью стандартного конструктора, без аргументов, но его нет. Это легко решается добавлением вызова другого конструктора:
Square::Square(double x, double y, double size):center_pt(x/size, y/size)
{...

Но если значения невозможно так просто посчитать, если в конструкторе происходит вычисление этих значений или переменные не заданы, а считываются допустим с датчика или ещё какой вариант, когда до выполнения конструктора Square нельзя получить параметры для Point, как тогда поступать?
Добавление конструктора для Point без параметров, не подходит, так как в реальной задачи это внешняя библиотека и ей изменение недопустимо.
  • Вопрос задан
  • 120 просмотров
Решения вопроса 2
@Mercury13
Программист на «си с крестами» и не только
center_pt = *new Point(x/size, y/size);
Утечка памяти. Никто в «си с крестами» за вас не будет подчищать все эти new.
Правильно:
center_pt = Point(x/size, y/size);
(Ну и, разумеется, я не понимаю, что значат эти x/size и y/size, но шут с ним.)

Примерно таким образом и происходит переприсваивание объектов, если им оставили таки операцию =. То есть…
class Geolocator {
public:
  Point coords;
  bool isReliable;

  Geolocator() : coords(0,0), isReliable(false) {}

  void getFromSensor() {
    coords = Point(100, 100);
    isReliable = true;
  }
};


Вариант 2. Через указатель, создание и уничтожение. Для простоты не буду это делать «руками», а воспользуюсь указателем единоличного владения unique_ptr.
class Geolocator {
public:
  std::unique_ptr<Point> coords;

  void getFromSensor() {
    Point pt(100, 100);
    if (coords) {
      *coords = pt;
    } else {
      coords.reset(new Point(pt));
    }
    // а если и операции = у Point нет, то можно
    // coords.reset(new Point(100, 100));
  }

  void declareUnreliable() {
    coords.reset();
  }
};
Ответ написан
myjcom
@myjcom Куратор тега C++
Значения по умолчанию
class Point
{
    double x_coord;
    double y_coord;
  public:
    Point(double x = {}, double y = {}) : x_coord{x}, y_coord{y}
    {
    }
};

class Square
{
    Point* center_pt;
    double size;
  public:
    Square(double x = {}, double y = {}, double sz = {1}) 
     : center_pt{new Point(x / sz, y / sz)}, size{sz}
    {
    }
    ~Square(){ delete center_pt; }
};

int main()
{
  Square sq(10, 10, 2);
  Square sq2();
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы