关于QList类型实例的复制构造函数的奇怪问题
A strange question about copy constructor for QList type instance
下面给出了一段代码的概要来演示问题,感谢您的宝贵时间。
在RowOfData rowData = tableData[row];
,RowOfData
复制构造函数将被调用并执行浅拷贝。
在tableData[row][col] = item;
时,QtParameter
复制构造函数将被tableData[row][col]
赋值操作调用,然后调用QList<T>::node_copy
所以将分配新条目 tableData[row][col]
。
问题:
为什么 tableData[row][col]
会调用 QtParameter
复制构造函数?
顺便说一句,当 rowData
在函数结束时被析构时,QtParameter
不会为 tableData[row][col]
调用复制构造函数。
类:
QtParameter::QtParameter( const QtParameter& rhs) :QVariant(rhs){}
class RowOfData : QList<QtParameter>
{
public:
RowOfData(const RowOfData& rhs);
private:
}
class TableData
{
public :
TableData();
virtual ~TableData();
bool setItem(int row, int col, QtParameter item);
protected:
QStringList columnHeader;
QStringList rowHeader;
QStringList rowFooter;
QList< RowOfData > tableData;
}
成员函数:
bool TableData::setItem(int row, int col, QtParameter item)
{
if(row<rowCount())
{
RowOfData rowData = tableData[row];
/*useless here and impact the tableData[row][col] copy constructer× */
if( col < tableData.at(row).size() )
{
tableData[row][col] = item;
}
}
}
template <typename T>
Q_INLINE_TEMPLATE void QList<T>::node_copy(Node *from, Node *to, Node *src)
{
Node *current = from;
if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
QT_TRY {
while(current != to) {
current->v = new T(*reinterpret_cast<T*>(src->v));
++current;
++src;
}
} QT_CATCH(...) {
while (current-- != from)
delete reinterpret_cast<T*>(current->v);
QT_RETHROW;
}
...
}
一种可能性是当成员函数 TableData::setItem
被类型 QtParameter
的对象调用时,因为该函数不是通过引用获取它,类型 QtParameter
的对象必须通过从前一个复制构造在函数内部创建!
如果你想避免这种情况,请参考它(最好是 const one):
bool TableData::setItem(int row, int col, const QtParameter& item)
继续前进,在函数内部:
RowOfData rowData = tableData[row];
有很小的可能性,如果这些不是 iterator/pointer 中的某些 type/s 的最低水平,这也可能是来源。
终于在:
tableData[row][col] = item;
根据您提到的情况,另一种可能是赋值运算符本身为 tableData[row][col]
的 class 定义的方式。
请记住,赋值运算符也是一个函数,如果它没有像这样声明:
assigned_to & operator=(const assigned_from &)
例如:
assigned_to & operator=(assigned_from)
与第一种情况相同,assigned_from 的对象将在赋值运算符内复制构造。
很多信息都没有给出,如果 "Deep copy" 你指的是 QList<T>::node_copy
,复制构造函数也可以发生在里面:
current->v = new T(*reinterpret_cast<T*>(src->v));
这是对 a 复制构造函数的明确调用。但是由于没有给出有关类型的信息,我不能肯定地说,这是调用 the 复制构造函数的地方。
此外,除非您提供一些有关 QList<QtParameter>
的信息,否则我无法解释为什么 rowData
被破坏时 "Deep copy" 没有发生。
下面给出了一段代码的概要来演示问题,感谢您的宝贵时间。
在
RowOfData rowData = tableData[row];
,RowOfData
复制构造函数将被调用并执行浅拷贝。在
tableData[row][col] = item;
时,QtParameter
复制构造函数将被tableData[row][col]
赋值操作调用,然后调用QList<T>::node_copy
所以将分配新条目tableData[row][col]
。问题: 为什么
tableData[row][col]
会调用QtParameter
复制构造函数?顺便说一句,当
rowData
在函数结束时被析构时,QtParameter
不会为tableData[row][col]
调用复制构造函数。
类:
QtParameter::QtParameter( const QtParameter& rhs) :QVariant(rhs){}
class RowOfData : QList<QtParameter>
{
public:
RowOfData(const RowOfData& rhs);
private:
}
class TableData
{
public :
TableData();
virtual ~TableData();
bool setItem(int row, int col, QtParameter item);
protected:
QStringList columnHeader;
QStringList rowHeader;
QStringList rowFooter;
QList< RowOfData > tableData;
}
成员函数:
bool TableData::setItem(int row, int col, QtParameter item)
{
if(row<rowCount())
{
RowOfData rowData = tableData[row];
/*useless here and impact the tableData[row][col] copy constructer× */
if( col < tableData.at(row).size() )
{
tableData[row][col] = item;
}
}
}
template <typename T>
Q_INLINE_TEMPLATE void QList<T>::node_copy(Node *from, Node *to, Node *src)
{
Node *current = from;
if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
QT_TRY {
while(current != to) {
current->v = new T(*reinterpret_cast<T*>(src->v));
++current;
++src;
}
} QT_CATCH(...) {
while (current-- != from)
delete reinterpret_cast<T*>(current->v);
QT_RETHROW;
}
...
}
一种可能性是当成员函数 TableData::setItem
被类型 QtParameter
的对象调用时,因为该函数不是通过引用获取它,类型 QtParameter
的对象必须通过从前一个复制构造在函数内部创建!
如果你想避免这种情况,请参考它(最好是 const one):
bool TableData::setItem(int row, int col, const QtParameter& item)
继续前进,在函数内部:
RowOfData rowData = tableData[row];
有很小的可能性,如果这些不是 iterator/pointer 中的某些 type/s 的最低水平,这也可能是来源。
终于在:
tableData[row][col] = item;
根据您提到的情况,另一种可能是赋值运算符本身为 tableData[row][col]
的 class 定义的方式。
请记住,赋值运算符也是一个函数,如果它没有像这样声明:
assigned_to & operator=(const assigned_from &)
例如:
assigned_to & operator=(assigned_from)
与第一种情况相同,assigned_from 的对象将在赋值运算符内复制构造。
很多信息都没有给出,如果 "Deep copy" 你指的是 QList<T>::node_copy
,复制构造函数也可以发生在里面:
current->v = new T(*reinterpret_cast<T*>(src->v));
这是对 a 复制构造函数的明确调用。但是由于没有给出有关类型的信息,我不能肯定地说,这是调用 the 复制构造函数的地方。
此外,除非您提供一些有关 QList<QtParameter>
的信息,否则我无法解释为什么 rowData
被破坏时 "Deep copy" 没有发生。