我正在尝试使用QSharedData来创建类型系统。这个想法很简单,将有许多不同的数据类型,每种数据类型都将从基本抽象类派生。我想使用QSharedData将实际数据存储在每个数据中,但是每个派生类将在其中存储不同的数据。我正在尝试提出最基本的示例,并且遇到了一些麻烦。

假设这些是我的基础纯虚拟类:

class cAbstractData: public QSharedData
{
public:
    cAbstractData(){ }
    virtual int type() = 0;
};

class cAbstractValue
{
public:
    cAbstractValue(){ }
    virtual int type() = 0;
protected:
    QSharedDataPointer<cAbstractData>data_;
};

现在,假设我要创建一个用于表示单个值的类(作为最小示例)。我从基值类派生了cAtomicValue,我还派生了一个数据类来保存该值:
class cAtomicData:public cAbstractData
{
public:
    cAtomicData() { value_ = 0; }
    int type(){ return 1; }
    QVariant value_;//the actual value
};

class cAtomicValue:public cAbstractValue
{
public:
    cAtomicValue() {
        data_ = new cAtomicData;//creating the data object.
    }
    int type(){ return 1; }
};

现在,在此阶段它可以正常工作,并且在调试器中,我可以看到正确的指针类型。但是现在我想添加一个用于设置和获取值的函数,但我不知道如何去做。让我们以二传手为例。要设置该值,我们必须通过value_类的cAtomicData成员访问data_类的cAtomicValue成员。但是,由于data_拥有一个基类指针(cAbstractData),因此我必须以某种方式将其强制转换为正确的类型(cAtomicData)。我尝试这样做:
template<class T> void set( T value )
{
    static_cast<cAtomicData*>(data_.data())->value_ = value;
}

它显然不起作用,因为它调用了detach()并尝试创建基类的拷贝,因为基类是纯虚拟的,所以它无法创建该拷贝。然后,我尝试强制转换指针本身:
static_cast<cAtomicData*>(data_)->value_ = value;

但我收到了invalid static_cast ...错误。

我该怎么做,我是否甚至从根本上以正确的方式来做?

最佳答案

我看不到有什么方法可以实现您在此处尝试的目标。正如您所发现的,QSharedDataPointer需要根据其包含的实际类型进行模板化。

您可以将您的基类作为模板,例如

template<class T>
class cAbstractValue
{
public:
    cAbstractValue(){ }
    virtual int type() = 0;
protected:
    QSharedDataPointer<T> data_;
};

但是我不确定我会从中得到什么好处。

10-07 17:47