Sin*_*all 5 c++ qt reference-counting qshareddata
我正在尝试使用时使用类型系统QSharedData
.这个想法很简单,会有许多不同的数据类型,每个类型都将从基础抽象类派生.我想用它QSharedData
来存储每一个中的实际数据,但是每个派生类都会在里面存储不同的数据.我现在正试图做出最基本的例子,并遇到一些麻烦.
假设这些是我的基本纯虚拟类:
class cAbstractData: public QSharedData
{
public:
cAbstractData(){ }
virtual int type() = 0;
};
class cAbstractValue
{
public:
cAbstractValue(){ }
virtual int type() = 0;
protected:
QSharedDataPointer<cAbstractData>data_;
};
Run Code Online (Sandbox Code Playgroud)
现在让我们说我想创建一个表示单个值的类(作为一个简单的例子).我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; }
};
Run Code Online (Sandbox Code Playgroud)
现在在这个阶段它工作得很好,在调试器中我可以看到正确的指针类型.但现在我想添加一个设置和获取值的函数,我不明白该怎么做.我们以制定者为例.要设置值,我们必须访问value_
的成员cAtomicData
通过类data_
的成员cAtomicValue
类.但是由于data_
保存了一个基类指针(cAbstractData
),我必须以cAtomicData
某种方式将它转换为正确的类型().我试过这样做:
template<class T> void set( T value )
{
static_cast<cAtomicData*>(data_.data())->value_ = value;
}
Run Code Online (Sandbox Code Playgroud)
它显然不起作用,因为它调用detach()
并尝试制作它不能的基类的副本,因为基类是纯虚拟的.然后我试着投射指针本身:
static_cast<cAtomicData*>(data_)->value_ = value;
Run Code Online (Sandbox Code Playgroud)
但我收到了一个invalid static_cast ...
错误.
我该怎么做,我是否从根本上以正确的方式做到了这一点?
你可以切换到QExplicitlySharedDataPointer
而不是QSharedDataPointer
.detach()
每当您尝试获取指向cAbstractData
对象的非const指针时,都不会调用此方法,包括将QExplicitlySharedDataPointer<cAbstractData>
对象强制转换为QExplicitlySharedDataPointer<cAtomicData>
对象.但是,如果要使用copy-on-write detach()
,cAbstractData
则每次要对其进行修改时都需要手动调用.也许你可以编写一个包装类来为你执行分离.
此方法可能优先使用QSharedPointer
,因为a QExplicitlySharedDataPointer
与普通指针的大小相同(因此保持二进制兼容性),而a QSharedPointer
的大小是两倍(参见此博客条目).
编辑:请注意,来自QExplicitlySharedDataPointer<cAbstractData>
to 的强制转换QExplicitlySharedDataPointer<cAtomicData>
是静态的,因此您必须保证实际引用的对象是该类型cAtomicData
(或子类)的对象,或者使用指针时的行为可能是未定义的.
我看不出有什么方法可以实现您在这里尝试的目标。正如您所发现的,QSharedDataPointer
需要根据它包含的实际类型进行模板化。
您可以将基类设为模板,例如
template<class T>
class cAbstractValue
{
public:
cAbstractValue(){ }
virtual int type() = 0;
protected:
QSharedDataPointer<T> data_;
};
Run Code Online (Sandbox Code Playgroud)
但我不确定你会从中得到什么好处。
归档时间: |
|
查看次数: |
2061 次 |
最近记录: |