【问题标题】:A strange question about copy constructor for QList type instance关于 QList 类型实例的复制构造函数的一个奇怪问题
【发布时间】:2019-05-16 02:49:29
【问题描述】:

下面给出了代码概要来演示问题,感谢您的时间。

  1. RowOfData rowData = tableData[row];RowOfData 将调用复制构造函数并执行浅复制。

  2. tableData[row][col] = item;QtParameter 复制构造函数将被tableData[row][col] 赋值操作调用,随后将调用QList<T>::node_copy,因此将分配新条目tableData[row][col]

    • 问题: 为什么tableData[row][col] 会调用QtParameter 复制构造函数?

    • 顺便说一句,当 rowData 在函数结束时被破坏时,不会为 tableData[row][col] 调用 QtParameter 复制构造函数。

类:

            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[row][col]”中为 QList 触发深层复制执行 [] 操作。但是问题是为什么删除 RowOfData rowData = tableData[row]; ,没有深拷贝操作。
  • 我写了一个答案。如果它解决了问题,请考虑投票/接受它! (stackoverflow.com/help/someone-answers)

标签: c++ qt copy-constructor qlist


【解决方案1】:

一种可能性是,当成员函数 TableData::setItemQtParameter 类型的对象调用时,因为该函数不是通过引用获取它,所以必须通过复制构造在函数内部创建 QtParameter 类型的对象从上一个开始!

如果你想避免这种情况,请通过引用(最好是 const one):

bool TableData::setItem(int row, int col, const QtParameter& item)

前进,在函数内部:

RowOfData rowData = tableData[row];

如果这些不是最低级别的迭代器/指针的某种类型/s 的可能性很小,那么这也可能是源。

终于在:

tableData[row][col] = item;

根据您提到的另一种可能性可能是赋值运算符本身为tableData[row][col] 类定义的方式。 请记住,赋值运算符也是一个函数,如果它没有被声明为:

assigned_to & operator=(const assigned_from &)

例如:

assigned_to & operator=(assigned_from)

与第一种情况相同,assigned_from 的对象将在赋值运算符内复制构造。

很多信息没有给出,如果你指的是QList&lt;T&gt;::node_copy的“深拷贝”,复制构造函数也可以发生在里面:

current->v = new T(*reinterpret_cast<T*>(src->v));

这是对 a 复制构造函数的明确调用。但是由于没有给出有关类型的信息,我不能肯定地说,这是调用 复制构造函数的地方。

此外,除非您提供有关 QList&lt;QtParameter&gt; 的一些信息,否则我无法说明为什么在 rowData 被破坏时没有发生“深拷贝”。

【讨论】:

  • 感谢您的回复,@AKL,仍有一些地方不清楚 1)实际上在进入函数时发生了 item 对象的复制构造函数,2)tableData[row] before = opration 的深层复制 3)为什么删除 RowOfData rowData = tableData[row] 顺便说一句,我尝试使用引用时不会发生深层复制操作,问题仍然存在。
  • HI Akl,现在我正在考虑为什么要添加 RowOfData rowData = tableData[row];会导致 tableData[row] 的深拷贝,我有一个假设不确定,因为 RowOfData rowData = tableData[row] 会调用拷贝构造函数,它是一个燕子拷贝,当退出函数 rowData 时会释放它的内存,编译器可能会让 tableData[row] 做深拷贝,否则动态内存会释放。我想编译器会影响,但我不确定。
  • @water 嗨,朋友让我想一想 :) 你试过rowData = std::move(tableData[row]) 吗?
  • @water 也请尝试RowOfData rowData(std::move(ableData[row])); 。对于标题#include &lt;utility&gt;
  • rowData = std::move(tableData[row]) , RowOfData rowData(std::move(ableData[row]));将调用 RowOfData::RowOfData(const RowOfData& rhs) 复制构造函数,然后问题仍然存在,感谢您的建议
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-02
相关资源
最近更新 更多