C++ 使用基类派生的模板类的正确类型转换从基类访问数据
我有以下情况:C++ 使用基类派生的模板类的正确类型转换从基类访问数据,c++,c++11,templates,C++,C++11,Templates,我有以下情况: class ScalarField { void* _buffer; //Array for data. }; 和派生类: template <typename T> class ScalarFieldT : public ScalarField { ScalarFieldT(int size) { _data = new T[size]; _buffer = _data; } T& get
class ScalarField
{
void* _buffer; //Array for data.
};
和派生类:
template <typename T>
class ScalarFieldT : public ScalarField
{
ScalarFieldT(int size)
{
_data = new T[size];
_buffer = _data;
}
T& get(int index)
{
return _data[index];
}
T* _data; // Typed array for data
};
关键是,我只能访问基类抽象,但我需要从\u buffer
获取转换为另一种简单数据类型的值,如float、int、uchar等
你们推荐什么
提前谢谢 嗯-请不要为了一个可能愚蠢的回答而对我扔石头,但是 让我们假设
T
仅限于数字数据类型,例如int
、long
、double
、float
,并进一步假设要存储的最大整数值约为2^53。然后,double
可以用作数据交换数据类型,任何其他数据类型都可以转换为该数据类型,而不会丢失精度
然后可以定义virtualdouble-ScalarField::method(int-index)=0
,然后在类型化变量中相应地重载它,这些变量执行从实际类型T
到双精度的“向上”转换
除非允许您将值封装在对象中(例如结构/类值),否则使用“use double as data exchange数据类型”的以下代码可以工作:
类ScalarField
{
公众:
void*\u buffer;//数据的数组。
虚双法(整数指数)=0;
};
模板
类ScalarFieldT:公共ScalarField
{
公众:
ScalarFieldT(整数大小)
{
_数据=新T[尺寸];
_缓冲区=_数据;
}
虚双精度方法(int-index){return get(index);}
T&get(整数索引)
{
返回数据[索引];
}
T*\u data;//数据的类型化数组
};
您可以使用提供一组强制转换运算符的类型作为方法的返回类型
下面是一个简单的工作示例:
#include<memory>
class ScalarField {
protected:
struct Value {
virtual operator float() const = 0;
virtual operator int() const = 0;
// ...
};
public:
virtual const Value & method(int i) = 0;
protected:
void* buffer;
};
template <typename T>
class ScalarFieldT : public ScalarField {
struct TValue: Value {
TValue(T value): value{value} {}
operator float() const override { return float(value); }
operator int() const override { return int(value); }
// ...
private:
T value;
};
public:
ScalarFieldT(int size) {
data = new T[size];
buffer = data;
}
T& get(int index) {
return data[index];
}
const Value & method(int i) {
std::make_unique<TValue>(data[i]);
}
private:
std::unique_ptr<Value> value;
T* data;
};
int main() {
ScalarFieldT<int> typedScalarField(10);
ScalarField* scalarField = &typedScalarField;
float f = scalarField->method(2);
int i = scalarField->method(5);
}
#包括
类ScalarField{
受保护的:
结构值{
虚拟运算符float()常量=0;
虚拟运算符int()常量=0;
// ...
};
公众:
虚拟常量值和方法(int i)=0;
受保护的:
空*缓冲区;
};
模板
类ScalarFieldT:公共ScalarField{
structValue:Value{
TValue(T值):值{value}{}
运算符float()常量重写{return float(value);}
运算符int()常量重写{return int(value);}
// ...
私人:
T值;
};
公众:
ScalarFieldT(整数大小){
数据=新T[尺寸];
缓冲区=数据;
}
T&get(整数索引){
返回数据[索引];
}
常量值和方法(int i){
标准::使_唯一(数据[i]);
}
私人:
std::唯一的ptr值;
T*数据;
};
int main(){
ScalarFieldT类型的Scalarfield(10);
ScalarField*ScalarField=&typedScalarField;
float f=scalarField->method(2);
int i=scalarField->method(5);
}
您希望在该main()
示例中将int
转换为float
,还是希望100%确保float value=scalarField->get(index)代码>只会被实例化为ScalarFieldT
的scalarField调用?使用static\u cast
。因此,基本上,您所拥有的只是一个void*
指针,而不知道它可能指向什么?那恐怕你用那个指针也没用了。您必须重新审视您的设计。我对您试图解决的问题或您必须努力解决的约束条件了解不够,无法提供建议。@JoãoPauloNavarro是一个可行的解决方案?让我知道,我会把它放在一个答案,如果它适合你。它或多或少地执行您要求的操作,即从底层缓冲区提取参数,将其转换为原始类型,然后转换为请求的类型。
#include<memory>
class ScalarField {
protected:
struct Value {
virtual operator float() const = 0;
virtual operator int() const = 0;
// ...
};
public:
virtual const Value & method(int i) = 0;
protected:
void* buffer;
};
template <typename T>
class ScalarFieldT : public ScalarField {
struct TValue: Value {
TValue(T value): value{value} {}
operator float() const override { return float(value); }
operator int() const override { return int(value); }
// ...
private:
T value;
};
public:
ScalarFieldT(int size) {
data = new T[size];
buffer = data;
}
T& get(int index) {
return data[index];
}
const Value & method(int i) {
std::make_unique<TValue>(data[i]);
}
private:
std::unique_ptr<Value> value;
T* data;
};
int main() {
ScalarFieldT<int> typedScalarField(10);
ScalarField* scalarField = &typedScalarField;
float f = scalarField->method(2);
int i = scalarField->method(5);
}