Точка и класс Строки в C++?

На других языках эта функция называется объединением. Как в sql. По-видимому, нет встроенной функции, но здесь обсуждаются различные подходы для ее реализации C # нуль-оператор объединения, эквивалентный для c ++

7
задан 19 February 2009 в 11:31
поделиться

11 ответов

Я предпочел бы это...

class Point
{
    private:
        int x, y;
    public:
        Point() : x(0), y(0) {}
        Point(int x, int y) : x(x), y(y) {}
}

class Line
{
    private:
        Point p1;
        Point p2;
    public:
        Line(const Point &p1, const Point &p2) : p1(p1), p2(p2) {}

        void setPoints(const Point &p1, const Point &p2)
        {
            this->p1 = p1;
            this->p2 = p2;
        }
}
2
ответ дан 6 December 2019 в 07:52
поделиться

+1, что сказанный zabzonk.

Время для использования указателей, поскольку Вы использовали их, было бы:

  1. У Вас есть несколько точек
  2. Вы хотите создать строки с помощью тех точек
  3. Вы хотите изменить значения точек и изменить строки неявно.

Шаг 3 выше может быть достигнут, если строки содержат указатели на существующие точки. Это представляет сложность, хотя (например, "при уничтожении экземпляра Точки что происходит с экземплярами Строки, которые содержат указатели на Точку?"), который не существует, когда (как zabzonk предложенный) каждая Строка содержит свои собственные значения Точки.

5
ответ дан 6 December 2019 в 07:52
поделиться

Вы не должны использовать указатели вообще в Вашем коде. Используйте фактические объекты. Указатели на самом деле используются вполне редко в C++.

class Point
{
    private:
        int x, y;
    public:
        Point() : x(0), y(0) {}
        Point(int x, int y) : x(x), y(y) {}
}

class Line
{
    private:
        Point p1;
        Point p2;
    public:
        Line(const Point & p1, const Point & p2 ) : p1(p1), p2(p2) {}

        void setPoints( const Point & ap1, const Point & ap2)
        {
            p1 = ap1;
            p2 = ap2;
        }
}
7
ответ дан 6 December 2019 в 07:52
поделиться

Являются ли члены Точки Вашего класса строки указателями, или не создает совсем другой тип класса. Используя указатели приведет к классическому подходу стиля CoGo, который может считаться точками, бывшими похожими на гвозди в плате и строки, являющиеся круглыми резинками, соединяющими те гвозди. Изменение точки похоже на перемещение гвоздя, все связанные работы строки автоматически следует, который желателен в определенных приложениях.

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

Это - критическое проектное решение для Ваших классов на данном этапе.

Править: Как отмечено в других сообщениях и комментарии ниже, используя простые указатели для достижения ассоциации между несколькими строками и точками также представляет серьезную потенциальную проблему. А именно, если точка удалена или перемещена в памяти, все указатели, относящиеся к той точке, должны быть обновлены. На практике это имеет тенденцию быть преодоленным при помощи уникальных идентификаторов точки для поиска точки, а не простых указателей. Это также позволяет структурам CoGo быть легко сериализированными / сохраненный. Таким образом наш класс точки имел бы статического участника для понимания мысли на основе идентификатора, и наш класс строки будет иметь два идентификатора точки, а не указатели.

5
ответ дан 6 December 2019 в 07:52
поделиться

Несколько вещей я заметил:

  • Можно объединить обоих из конструкторов точки в единственного конструктора со значениями по умолчанию.
  • Ваше использование указателей является довольно ненужным. Используйте сам объект.
  • Вы используете и указатели и ссылки попеременно. Не перепутывайте их или смотрите последнюю точку.
1
ответ дан 6 December 2019 в 07:52
поделиться

Нет никакой потребности использовать указатели в Вашем классе Строки.

Кроме того, следующая строка является неправильной:

Line(Point &p1, Point &p2) : p1(p1), p2(p2) {}

Почему? Вы присваиваете a Point & (p1) к a Point * (Строка:: p1), который недопустим. Вы хотели бы указатели там.

Ваш класс Точки не имеет никакого способа изменить его данные. Не слишком полезный...

Класс Строки для меня выглядел бы примерно так:

class Line
{
    private:
        Point p1, p2;

    public:
        Line()
        {
        }

        Line(Point start, Point end) :
            p1(start), p2(end)
        {
        }

        const Point &startPoint() const
        {
            return p1;
        }

        Point &startPoint()
        {
            return p1;
        }

        const Point &endPoint() const
        {
            return p2;
        }

        Point &endPoint()
        {
            return p2;
        }
};

Можно теперь отредактировать строку как это:

Line line;
line.startPoint() = Point(4, 2);
line.endPoint() = Point(6, 9);
2
ответ дан 6 December 2019 в 07:52
поделиться

Я вижу мало значения в создании указателей Точки (кроме для железного значения). Ваша Точка берет 8 байтов в системе на 32 бита (2 интервала). Указатель берет 4 байта. Вы сохраняете 4 байта.

Что касается правильности, Ваш конструктор Line берет ссылки, но Вы присваиваете их указателям. Это не должно даже компилировать. Вы также делаете то же самое в заданных значениях. Было бы лучше просто сделать два фактических объекта точек и копирование их значений.

1
ответ дан 6 December 2019 в 07:52
поделиться
class Line
{
    private:
        Point *p1; /* No memory allocated */
        Point *p2; /* No memory allocated */
    public:
        Line(Point &p1, Point &p2) : p1(p1), p2(p2) {}

        void setPoints(Point &p1, Point &p2) /* passed references to Point objects */
        {
            this->p1 = p1; /* asssiging Point objects to Point *! */
            this->p2 = p2; /* asssiging Point objects to Point *! */
        }
}

Заданные значения () функция не работали бы - на первый взгляд. Это должно быть

            void setPoints(Point &p1, Point &p2) 
            {
                this->p1 = &p1; /* asssiging Point objects to Point *! */
                this->p2 = &p2; /* asssiging Point objects to Point *! */
            }

С другой стороны мы не управляем, когда p1 и p2 уничтожаются. Лучше создать это-> p1 и это-> p2 использование данных в p1 и p2 так, чтобы деструктор управлял памятью

0
ответ дан 6 December 2019 в 07:52
поделиться

Компилятор даст ошибки на этом коде:

  1. В списке инициализации конструктора Line Вы присваиваете ссылку Точки p1 участнику класса p1, который является указателем на Точку. Чтобы заставить это компилировать, необходимо использовать Строку (Точка &p1, Точка &p2): p1 (&p1), p2 (&p2).
  2. Та же проблема происходит в методе заданных значений. Это должно быть изменено на это-> p1 = &p1 и т.д.
  3. Незначительная проблема: после закрытия} класса, вставленного в точку с запятой (;)

Я думаю, что это завершает синтаксис.

Существует другая проблема с кодом:

p1 и p2 члены класса Строки являются указателями для Указания на экземпляры. Кто создает эти экземпляры и кто удалит их, когда они больше будут не нужны? При разработке класса, как это теперь, код, который создает экземпляр Строки, передает два экземпляра Точки конструктору. Если эти экземпляры Точки удалены, прежде чем Строка, Строку оставляют с двумя висячими указателями (указатели, которые больше не относятся к допустимому экземпляру).

Кроме того, два экземпляра Точки, которые являются теперь частью Строки, могут быть изменены из кода за пределами класса Строки. Это может привести к очень нежелательным ситуациям.

В этой ситуации я объявил бы p1 и p2 участников как Точка (вместо указателя на Точку). Тем путем экземпляры Точки, которые передаются конструктору, копируются в участников класса. Пока Строка существует, участники Точки будут существовать. Они могут только быть изменены самим классом строки.

0
ответ дан 6 December 2019 в 07:52
поделиться

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

Кажется, что больше всего здесь соглашаются, что необходимо использовать семантику значения на такой небольшой кодовой базе. Иногда, проблема требует, чтобы тот же объект (т.е. Точка) был сослан многими сторонами, затем используйте указатели (или ссылки).

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

0
ответ дан 6 December 2019 в 07:52
поделиться

Используйте Точечные объекты в своем классе Строки. Владение точек неясно, и Вы рискуете заканчивать с висячими указателями или пропустили память.

Ваш конструктор по умолчанию является проблемой, поскольку Вы будете редко хотеть создать Точку в (0,0). Вы - более обеспеченная установка значения по умолчанию x, y оценивает чему-то как MAXINT и утверждая, что любое использование Точки не имеет MAXINT как одного из его значений. Имейте is_valid () функция так, чтобы клиенты могли протестировать. Ваш класс Строки может также иметь предварительное условие, что его два вопроса являются весьма актуальными. Плата прочь не разрешения актуального вопроса иметь значение MAXINT - то, что можно обнаружить, когда Точки не были инициализированы правильно, и Вы убьете некоторых в других отношениях трудных найти ошибки в использовании класса.

0
ответ дан 6 December 2019 в 07:52
поделиться
Другие вопросы по тегам:

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