在有限元代码中,我有一个数据结构来操纵某个点的字段值(坐标、温度...)。这个结构是基本的,看起来像这样:
class point_data
{
public:
void allocate(int ldim); // allocation of data;
const double* get_data() const { return data; }
void set_data(const double* ldata); // for example
…
protected:
double* data;
…
}
然后我使用 point_data*
类型的对象评估表达式,例如施加边界条件。具体来说,如果 x、y 是坐标域,并且我在 x == 0 定义的边界上施加一个等于 sin(y) 的温度 T,那么我有一个“sin”运算符对象,其 evaluate 方法采用point_data*
参数(实际上是一个 point_data**
)并返回一个 point_data*
包含结果。我的“==”对象也一样,它也需要一个 point_data**
。参数(这次是两个 point_data*
的数组)并返回结果。
因为我支持全局字段数据的结构已经是模板,而且正是这个结构创建了point_data
对象,我想模板化类 point_data
.然后,我尝试了:
class abstract_point_data
{
protected:
int dim;
public:
abstract_point_data() : dim{0} { ; }
virtual ~abstract_point_data() { ; }
const int& get_dim() const { return dim; }
void set_dim(int ldim) { dim = ldim; }
virtual void allocate(int ldim=0) = 0;
// get_data ??? set_data ???
};
template <typename T>
class point_data : public abstract_point_data
{
public:
point_data() : my_data{0}, allocated{false} { ; }
virtual ~point_data() { delete_data(); }
virtual void set_data(const T* ldata);
virtual const T* get_data() const { return my_data; }
virtual void allocate(int ldim);
protected:
T* my_data;
bool allocated;
void delete_data() { if ( allocated ) { delete [] my_data; allocated = false; } }
};
template <typename T>
void point_data<T>::allocate(int ldim)
{
dim = ldim;
delete_data();
my_data = new T[ldim];
allocated = true;
}
template <typename T>
void point_data<T>::set_data(const T* ldata)
{
for (int i=0; i<dim; i++)
my_data[i] = ldata[i];
}
主要是:
abstract_point_data* mp = new point_data<double>;
mp->allocate(1);
double val = 1.0;
( (point_data<double>*) mp)->set_data(&val);
delete mp;
这样,我的运算符对象的评估方法可以有一个 abstract_point_data**
作为论据。 In 也可以创建结果对象,因为我知道例如正弦提供 double ,或者通过克隆其中一个参数。但是,仅此而已。通常,我不知道评估函数中参数的类型,因此我不能(当然)访问 getter 和 setter。我试过 CRTP,decltype(auto)
,甚至像std::tuple<bool,int,double> my_types;
这样的愚蠢的东西+ decltype(std::get<get_my_index()>(my_types))
将我的模板类型存储在“abstract_point_data”中,但是不,C++ 规则似乎是不可侵犯的。
任何人都可以给我一个想法或引用来帮助我重新定义(如果可能的话)一个可接受的模板化数据结构吗?提前致谢。
此外:使用 abstract_point_data 的原因是(如果它有效)只处理 abstract_point_data 对象(作为方法参数,在容器中......),而不是处理 point_data<int>
, point_data<double
>, ...(但也许我漏掉了什么)。
最佳答案
这取决于你想达到什么目的。如果您想拥有类似 std::vector<std::unique_ptr<abstract_point_data>>
的东西,您当前拥有的抽象基本模式确实很有用。 .与 Ted Lyngmo 的评论相呼应,您可以避免内存管理的潜在麻烦,让容器或智能指针为您完成。智能指针支持多态性,所以你可以使用上面的 vector 来存储一个std::unique_ptr<point_data<double>>
。 .
要让您的函数/对象与派生类型一起工作,您也可以将它们设为模板,例如:
template<typename T, typename U>
bool operator==(point_data<T> const& x, point_data<U> const& y)
{ return x.get_data() == y.get_data(); }
关于c++ - 模板数据结构 - 访问从抽象类派生的模板类的 getter 和 setter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70439271/