我有以下基类:
class Network::ActivationFunction
{
public:
virtual double evaluate(double x) =0
virtual double evaluate_derivative(double x) =0
};
这意味着是神经网络中神经元的激活函数的基类。我希望有不同类型的sigmoids / relu / ...
我真的不想拥有任何特定激活函数的多个实例,所以我想做这样的事情:
class : public Network::ActivationFunction
{
public:
double evaluate(double x);
double evaluate_derivative(double x);
} logisticActivationFunction;
然后在.cpp文件中定义函数。但是,由于它是匿名的,我不知道如何在另一个文件中定义它的成员函数。
那么我怎样才能使上述想法发挥作用,或者以任何其他方式只有一个特定激活函数的实例?
我不知道如何在另一个文件中定义它的成员函数。
那是因为你做不到。无法在类定义之外定义未命名的†类的成员函数,因此无法在另一个文件中定义它们。
†一点技术迂腐:这堂课不是匿名的;它没有命名。
有什么不同?
未命名的类只是类,没有像您的示例类那样的名称。匿名类是另一个类的成员,其中类和成员对象都没有名称。例:
struct foo {
union { // no class name
int i;
char c;
}; // no name for the member object
}:
只有工会在C ++中可以是匿名的。匿名的非工会阶级是不正确的。 C中允许使用匿名结构(自C11起);这是语言不兼容的情况。
或以任何其他方式只有一个特定激活功能的实例?
好吧,只要你只实例化一次,那么只会有一个实例。如果程序的正确性只有一个实例很重要,那么您可以使用单例模式强制执行该实例。
Singleton可以通过使所有构造函数都为私有来实现,使得类不可复制(和不可移动)并编写一个静态成员工厂函数,该函数返回对本地静态实例的引用:
class LogisticActivationFunction : public Network::ActivationFunction
{
public:
static LogisticActivationFunction& get()
{
static LogisticActivationFunction obj;
return obj;
}
double evaluate(double x);
double evaluate_derivative(double x);
// prevent copying / moving
LogisticActivationFunction(LogisticActivationFunction const&) = delete;
private:
// allow only member functins to construct
LogisticActivationFunction() = default;
};
那么在头文件中只有定义的解决方案呢?
只是使类未命名不会阻止类的用户创建一个实例的副本,从而创建更多,因此从技术上讲,它不会强制要求只有一个实例。
无法声明未命名类的复制构造函数,因此您无法将它们声明为已删除或私有。防止复制的技巧可能是添加不可复制的不可移动的成员对象。但我会推荐上面描述的单例模式。