使用 shared_ptr 在 class 及其成员对象之间共享变量是一个好的解决方案吗?
Is using a shared_ptr to share variables between class and its member objects a good solution?
我这样做是为了在我所有的神经元之间共享 learning_rate
:
class neural_network {
public:
neural_network(float learning_rate = 0.005f)
: learning_rate(new float(learning_rate)){};
shared_ptr<float> learning_rate;
private:
vector<neuron> neurons;
};
class neuron {
public:
neuron(const float learning_rate) {
this->learningRate = make_shared<float>(learningRate);
};
private:
const shared_ptr<const float> learning_rate;
};
在我的所有神经元上使用相同的 learning_rate
是一个很好的解决方案吗?
shared_ptr
是共享所有权,不是"share an instance"。
某些实例 X
的生命周期与其成员之间存在明确定义的关系。在最简单的情况下,成员将一直存在,直到它们在 X
的析构函数中被销毁。成员通常不会在 X
的生命周期之后继续存活。因此,不需要共享所有权。您可以使用原始指针来强调 neurons
不参与 learning_rate
.
的所有权
class neural_network
{
public:
neural_network(float learning_rate = 0.005f)
: learning_rate(learnin_rate) {};
float learning_rate;
private:
vector<neuron> neurons;
}
class neuron
{
public:
neuron(const float* learning_rate) : learning_rate(learning_rate){}
private:
const float* learning_rate;
}
PS:不确定,但我想我会应用一个完全不同的设计。使 learning_rate
成为 neurons
的(非常量非指针)成员。然后,如果 neural_network
更改 learning_rate
,它将调用神经元 set_learning_rate
方法来更新它们的学习率。这样 neuron
s 就有机会在学习率变化时做出反应。
shared_ptr
相当昂贵,我认为这里不需要它,只有网络需要 "own" 学习率。不要害怕在适当的地方使用原始指针,只要避免 new
和 delete
:
class neuron {
public:
neuron(const float& learning_rate)
: learning_rate(&learning_rate){};
private:
const float* learning_rate;
};
class neural_network {
public:
neural_network(float learning_rate = 0.005f)
: learning_rate(learning_rate){};
float learning_rate;
void make_neuron()
{
neurons.push_back(neuron(learning_rate));
}
private:
vector<neuron> neurons;
};
对于单个 float
,我真的认为这一切都太过分了。如果你的学习率可以变得更复杂,那是一回事,但在此处给出的代码中呢?我建议只在 neural_network
中使用浮动成员,在构建期间在 neuron
中使用 const neural_network* owner;
。
然后你在 neural_network
上打一个 public getLearningRate()
就大功告成了。您可能需要跟踪各种网络范围的状态,因此单个神经元可以从一个指针中获得很多效用。示例可能是日志、序列化流或脏标志。
Bonus: No dynamic allocations, which is always a nice efficiency gain when you can get it. No pointer-related cache misses, no new
ing or delete
ing.
此外,我认为您在 neuron
的构造函数中对 make_shared()
的调用将创建一个新的共享指针,指向具有相同 float
值的新实例。这导致对根 learning_rate
的更改根本不会影响现有的 neuron
实例。 (还有很多额外的、不需要的内存分配)
我这样做是为了在我所有的神经元之间共享 learning_rate
:
class neural_network {
public:
neural_network(float learning_rate = 0.005f)
: learning_rate(new float(learning_rate)){};
shared_ptr<float> learning_rate;
private:
vector<neuron> neurons;
};
class neuron {
public:
neuron(const float learning_rate) {
this->learningRate = make_shared<float>(learningRate);
};
private:
const shared_ptr<const float> learning_rate;
};
在我的所有神经元上使用相同的 learning_rate
是一个很好的解决方案吗?
shared_ptr
是共享所有权,不是"share an instance"。
某些实例 X
的生命周期与其成员之间存在明确定义的关系。在最简单的情况下,成员将一直存在,直到它们在 X
的析构函数中被销毁。成员通常不会在 X
的生命周期之后继续存活。因此,不需要共享所有权。您可以使用原始指针来强调 neurons
不参与 learning_rate
.
class neural_network
{
public:
neural_network(float learning_rate = 0.005f)
: learning_rate(learnin_rate) {};
float learning_rate;
private:
vector<neuron> neurons;
}
class neuron
{
public:
neuron(const float* learning_rate) : learning_rate(learning_rate){}
private:
const float* learning_rate;
}
PS:不确定,但我想我会应用一个完全不同的设计。使 learning_rate
成为 neurons
的(非常量非指针)成员。然后,如果 neural_network
更改 learning_rate
,它将调用神经元 set_learning_rate
方法来更新它们的学习率。这样 neuron
s 就有机会在学习率变化时做出反应。
shared_ptr
相当昂贵,我认为这里不需要它,只有网络需要 "own" 学习率。不要害怕在适当的地方使用原始指针,只要避免 new
和 delete
:
class neuron {
public:
neuron(const float& learning_rate)
: learning_rate(&learning_rate){};
private:
const float* learning_rate;
};
class neural_network {
public:
neural_network(float learning_rate = 0.005f)
: learning_rate(learning_rate){};
float learning_rate;
void make_neuron()
{
neurons.push_back(neuron(learning_rate));
}
private:
vector<neuron> neurons;
};
对于单个 float
,我真的认为这一切都太过分了。如果你的学习率可以变得更复杂,那是一回事,但在此处给出的代码中呢?我建议只在 neural_network
中使用浮动成员,在构建期间在 neuron
中使用 const neural_network* owner;
。
然后你在 neural_network
上打一个 public getLearningRate()
就大功告成了。您可能需要跟踪各种网络范围的状态,因此单个神经元可以从一个指针中获得很多效用。示例可能是日志、序列化流或脏标志。
Bonus: No dynamic allocations, which is always a nice efficiency gain when you can get it. No pointer-related cache misses, no
new
ing ordelete
ing.
此外,我认为您在 neuron
的构造函数中对 make_shared()
的调用将创建一个新的共享指针,指向具有相同 float
值的新实例。这导致对根 learning_rate
的更改根本不会影响现有的 neuron
实例。 (还有很多额外的、不需要的内存分配)