选择要在编译时使用的派生类

Selecting which derived class to use at compile time

本文关键字:派生 编译 选择      更新时间:2023-10-16

我认为这是一个非常简单的问题,但我对C++的了解不足以让它听起来很简单。

我有定义抽象基类ContinuousDistribution和派生类(如CauchyNormal)的代码
我的目标是拥有变量A的默认定义,但允许用户更改该定义,特别是更改变量的类型。(我不是说运行时重新定义,而是编译时重新定义)

所以在默认文件中,我会有

默认.cpp

... 
Normal A(0., 20.);  // Normal is the default
....
x = A.logpdf();

其在假定默认CCD_ 5分布的情况下编译和运行。

然后我希望用户创建一个"配置"文件,在该文件中可以更改A的定义。在另一个将与default.cpp一起编译的文件中,我们可以有

user1.cpp

... 
Normal A(0., 10.);  // change the arguments of Normal
....
call some functions defined in default.cpp, which use methods of A
....

或另一个具有的

user2.cpp

... 
Cauchy A(0., 10.);  // change the type of A
....
call some functions defined in default.cpp, which use methods of A
....

为了解决这个问题,我尝试在default.cpp中使用extern Normal A,但这不允许将变量重新定义为Cauchy。我还在default.cpp中尝试了extern ContinuousDistribution A,但也不起作用。如果从default.cpp中删除了A的定义,则我无法使用error: ‘A’ was not declared in this scope进行编译,因为我使用A.logpdf()

我该如何解决这个问题?

正如一条评论中所建议的那样,我还尝试使用类似default.cpp中的Normal *A=new Normal(0,20);,并在user2.cpp中用A = new Cauchy(0,10);重新分配它,但随后user2.cpp由于A was not declared in this scope而不编译。

如果您使用标头(这是一种很好的做法,所以您应该这样做),您可以执行以下操作:

默认.h

#ifndef _default_h_
extern Normal *A;
#define _default_h_
#endif

默认.cpp

#include "default.h"
... 
Normal *A = new Normal(0., 20.);  // Normal is the default
....
x = A->logpdf();
...

user1.cpp

#include "default.h"
...
delete A; // Free up memory
A = new Normal(0., 10.);  // change the arguments of Normal
...
call some functions defined in default.cpp, which use methods of A
....

user2.cpp

#include "default.h"
...
delete A; // Free up memory
A = new Cauchy(0., 10.);  // change the arguments of Normal
...
call some functions defined in default.cpp, which use methods of A
....

Extern关键字告诉编译器在链接阶段的某个地方会有给定类型和名称的变量,并且使用基类指针可以将导数存储在自己中。