Оператор с несколькими точками (класс С++)

Мне нужно реализовать класс Vector, который устанавливает координаты многомерного вектора и будет работать при вызове с этим конкретным кодом (эту часть я не могу изменить):

  const int NumOfDimensions = 5;
  Vector x (NumOfDimensions);
  x.Set(0, 1.1).Set(1, 1.2).Set(2, 1.3).Set(3, 1.4).Set(4, 1.5); 
  x.print();

и вывод должен быть таким:

(1.1, 1.2, 1.3, 1.4, 1.5)

Это то, что я пробовал, но не смог заставить его работать:

class Vector {
float *coordinates;
int dimensions;

public:
Vector(int k)
{
coordinates = new float[k];
dimensions = k;
}
void Set(int k, float wsp)
{
    //Vector x(k+1);
    coordinates[k] = wsp;
    //return x;
}
void print()
{
    int i;
    cout<<"(";
    for(i=0; i<dimensions; i++)
    cout<<coordinates[i]<<", ";
    cout<<")"<<endl;
}
};

Итак, я знаю, что функцию Set нужно изменить и, возможно, вернуть объект, но я пробовал много разных способов, и это просто не работает. Как мне его изменить?


person mushisgosu    schedule 25.11.2016    source источник


Ответы (1)


Если вы хотите иметь возможность связывать методы такого рода, вам нужно вернуть ссылку:

Vector& Set(int k, float wsp) {
  // ...

  return *this;
}

Я бы сказал, что даже если вы видите много такого в других языках, таких как Python, Ruby и т. д., этот интерфейс не очень похож на C++.

Вам лучше использовать std::vector для хранения ваших coordinates, массивы в стиле C - не что иное, как проблемы. Этот код на самом деле имеет серьезную утечку памяти, поскольку вы не освобождаете память с помощью delete[], деструктор не определен. Использование контейнера стандартной библиотеки снимает эту ответственность.

Еще одна вещь, которую вы можете сделать, чтобы сделать это более родным для C++, — это определить форматировщик для него, чтобы вы могли просто сбросить это в cout вместо того, чтобы использовать неуклюжий метод с именем print, который сделает это за вас:

std::ostream& operator<<(std::ostream& stream, const Vector& vec);

Это позволит использовать этот форматтер в любом потоке, а не только в cout.

person tadman    schedule 25.11.2016
comment
Спасибо! это работает, не могу поверить, что я потратил на это 2 часа, а затем получил ответ через 1 минуту. - person mushisgosu; 26.11.2016
comment
Это необычный шаблон для использования в C++, и, вероятно, поэтому вы не видите в нем особого призыва. - person tadman; 26.11.2016
comment
@tadman, в этом нет ничего необычного. Я видел это несколько раз. googlemock — один из примеров, который я видел недавно. Но я думаю, это усложняется, если вы собираетесь использовать его, например, вместе с наследованием. - person Zitrax; 26.11.2016
comment
Он похож на шаблон Builder. - person Justin Time - Reinstate Monica; 26.11.2016
comment
@Zitrax Есть определенные школы объектно-ориентированного дизайна, которые любят его использовать, особенно в мире, основанном на Smalltalk. Некоторые из этих шаблонов проникли в некоторые базы кода C++. Я не говорю, что это хорошо или плохо, но просто в С++ это относительно редко, скорее всего, из-за проблем сложности, возникающих при наследовании, как вы указываете. Динамические языки здесь могут сойти с рук, C++ будет намного сложнее содержать в чистоте. - person tadman; 26.11.2016
comment
Разве он не согласен с использованием массива? Разве векторы не объявляются в памяти как постоянный размер до тех пор, пока емкость не будет превышена? - person Kenneth McKanders; 26.11.2016
comment
@KennethMcKanders Каждый контейнер стандартной библиотеки имеет разные характеристики производительности, поэтому выбор правильного часто означает выбор правильных компромиссов. std::vector допускает произвольный доступ, может произвольно изменять размер и быстро повторяется. Стоимость изменения размера не равна нулю, но обычно несущественна, если только вы не имеете дело с очень большими списками или сложными, дорогими для копирования объектами. - person tadman; 26.11.2016