2014-09-29 1 views
-2

Я начинающий C++, и я пытаюсь написать метод, который возьмет два вектора и добавит их содержимое.Добавление векторов в C++

Например, v1 {1,2,3} + v2 {2,4,6} должен давать v3 {3,6,9}.

Вот что мой код выглядит как прямо сейчас:

Vec Vec::operator+(const Vec& original){ 
    if(mySize != original.mySize){ 
    throw invalid_argument ("No!"); 
    } 
    Item* sumVector = new Item(mySize); 
    for(unsigned i=0; i<mySize; i++){ 
     sumVector[i] = myArray[i] + original.myArray[i]; 
    } 
    return * sumVector; 
} 

Однако, это не работает, потому что мое утверждение v3.getItem (0) == 3 не удается. Я уверен, что вы уже знаете это, если вы отвечаете на этот вопрос, но Vec - это имя одного из моих классов в этом, а Item - двойник typedef.

+3

'sumVector' - это указатель (ему не нужно быть, и его не должно быть.) Подумайте, что делает' operator [] 'при применении к указателю. – juanchopanza

+7

О, нет оператора утечки памяти! Почему вы возвращаете новый объект по стоимости? – Borgleader

+4

Привет приветствую _ @ TheFaceOfBlue_! Как насчет того, чтобы просто использовать ['std :: vector'] (http://en.cppreference.com/w/cpp/container/vector), прежде чем начинать свой собственный? Есть много препятствий и ошибок, чтобы сделать это правильно, и почти никогда не стоит того, чтобы придумать проприетарную реализацию. –

ответ

-2

Изменить это утверждение

Item* sumVector = new Item(mySize); 

в

Item* sumVector = new Item[mySize]; 

И вместо

return * sumVector; 

там должно быть

return sumVector; 

при условии, что класс Vec имеет конструктор с параметром типа Item * Однако в любом случае существует проблема с конструктором, потому что даже он имеет параметр типа Item *, он не знает, сколько элементов было выделено. Итак, вам нужно создать объект типа Vec внутри тела оператора.

Кроме того, было бы лучше, чтобы объявить оператор, как

Vec Vec::operator+(const Vec& original) const; 
+0

Хорошо, я сделал это, и он все еще не работает. Хм ... извините. Я уверен, что это простое решение, но, как я уже сказал, я новичок. – TheFaceOfBoe

+0

@TheFaceOfBoe Смотрите мое обновленное сообщение. –

+0

@TheFaceOfBoe Я добавил дополнительное замечание в свой пост о конструкторе, вам нужно создать объект типа Vec внутри тела оператора, потому что я не знаю, как конструктор будет знать, сколько элементов массива было выделено. –

2

Как juanchopanza упоминалось в комментариях, sumVector является указателем. К сожалению для вас, operator[] определен для указателей, которые, возможно, дали запутанную ошибку компиляции для новичков.

Для решения, которые наилучшим образом сохраняет ошибочное намерение исходного кода, это:

sumVector[i] = myArray[i] + original.myArray[i];

потребности быть таким:

(*sumVector)[i] = myArray[i] + original.myArray[i];

Таким образом, вы де-ссылка сначала указатель, затем введите operator[] для векторного класса. Это действительно плохо, хотя и, возможно, даже не решение.

Вы должны понимать, что делает ваш код. Вы назначаете новый массив Items на кучей, а затем возвращаете копию Vec с использованием *Item, что эквивалентно Item[0], в качестве конструктора Vec. Вы не только создаете Vec с одним двойным вводом (не видя объявления класса, я не знаю, действительно ли это, но это, вероятно, нет), но это распределение кучи Items никогда не будет иметь соответствующего бесплатного поскольку вы потеряли единственную ссылку на него, когда вы покидаете область действия. Вы никогда не сможете освободить память, а это значит, что это утечка памяти.

Правильное намерение (я предполагаю) состоит в том, чтобы создать локальный вектор в стеке с вычислениями, а затем вернуть его. Это означает, что изменение две строки:

Item* sumVector = new Item(mySize) 
return * sumVector; 

в

Vec sumVector(mySize); //now this is actually a vector 
return sumVector; 

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

+0

Хорошо, я думаю, это имеет смысл. Я собираюсь быть честным, хотя все эти указатели и разыгрывающие вещи по-прежнему немного сложны для понимания, поэтому мне придется учиться на этом. Я внес исправления, которые вы предложили, но теперь я думаю, что мои типы несовместимы, потому что я получаю ошибку 'invalid types 'Item {aka double} [unsigned int]' для индекса массива' on 'sumVector [i] = myArray [ i] + original.myArray [i]; ', который я не думаю, имеет смысл, потому что все три из этих аргументов - Item *, за исключением sumVector, который я только что изменил за ваше предложение. Извините. Спасибо за помощь! – TheFaceOfBoe

+0

oops Я хотел изменить 'Item' на' Vec'! Я предполагаю, что у вашего вектора есть конструктор, который принимает размер? – Suedocode