Вот перезапись вашего класса без копирования объекта и с использованием стандартной библиотеки C ++. В приведенном ниже примере используется std::vector
вместе с семантикой перемещения, чтобы избежать копирования данных. Комментарии идут после образца кода:
#include <vector>
#include <numeric>
#include <iostream>
class Neuron
{
private:
std::vector<double> weights; // We use a vector of doubles, not an array
double bias;
public:
Neuron(std::vector<double>&, double);
double forward_prop(const std::vector<double>&);
};
Neuron::Neuron(std::vector<double>& weights_, double bias_) : weights(std::move(weights_)), bias(bias_) // The std::move avoids the copy
{}
double Neuron::forward_prop(const std::vector<double>& values)
{
// the std::inner_product function does what your code is doing now
return std::inner_product(weights.begin(), weights.end(), values.begin(), bias);
}
int main()
{
std::vector<double> myWeights {1,2,3,4};
Neuron n(myWeights, 10);
std::cout << n.forward_prop({5,6,7,8});
}
Вывод:
80
Вот ключевые моменты:
std::vector
- это используется вместо массивов и указателей. Обратите внимание, что нам больше не нужна переменная-член num_weights
, поскольку вектор уже знает свой размер, вызвав функцию-член size()
для std::vector
.
в Neuron
конструктор, мы вызываем std::move
, когда присваиваем переданный вектор члену объекта. Это вызывает семантику перемещения, которая встроена в std::vector
. Обычно указатели, которые использует исходный вектор, «украдены» или перемещены в целевой вектор, что позволяет избежать копирования.
Обратите внимание, что исходный вектор будет изменен когда это будет сделано . Переданный вектор станет по существу пустым (помните, что его содержимое было перемещено).
В довершение всего, я реализовал ваш forward_prop
, используя std :: inner_product .
Дополнительные элементы - обратите внимание на использование список инициализации членов при написании конструкторов. Кроме того, при вызове forward_prop
используется синтаксис инициализации скобок std::vector
, поэтому, когда мы вызывали forward_prop
, не было необходимости явно объявлять std::vector<double>
.
Заметьте, что реальный момент, который нужно вывести из этого, заключается в том, что, начиная с C ++ 11, семантика перемещения была формально введена в язык. Это позволяет выполнять перемещение (вместо копирования) формальным образом.
Теперь, когда возможна семантика перемещения, были добавлены дополнительные функции (такие как std::move
, конструкторы перемещения и операторы присваивания перемещения, emplace_back
функции-члены в некоторых классах контейнеров STL, std::unique_ptr
работает вместо несколько сломанных std::auto_ptr
, и c.).
До C ++ 11 вам приходилось использовать "трюки" с указателями или надеюсь, что оптимизатор компилятора неявно переместил (хотя формального названия для этого типа операции не было).