这里虚拟运算符()()的目的是什么?

时间:2016-11-02 16:34:24

标签: c++ qt c++11 virtual operator-keyword

我试图修改code I found,但我对此虚拟运营商的目的,重要性和/或相关性缺乏了解而受阻:

  1. 有人可以提供有关此运算符为何必要或有用的信息吗?
  2. 我是否认为需要parentItem()rect_resizer_作为参数,然后修改resizer_的值?
  3. .h中的构造函数:

    virtual void operator()(QGraphicsItem* item, const QRectF& rect) = 0;

    拨入.cpp:

    (*resizer_)(parentItem(), rect_);

    修剪构造函数的上下文以供参考:

    class SizeGripItem : public QGraphicsItem
    {
        private:
    
            class HandleItem : public QGraphicsRectItem
            {
                public:
                    HandleItem(int positionFlags, SizeGripItem* parent);
    
                private:    
                    SizeGripItem* parent_;
            };
    
        public:
            class Resizer
            {
                public:
                    virtual void operator()(QGraphicsItem* item,
                                            const QRectF& rect) = 0;
            };
    
            SizeGripItem(Resizer* resizer = 0, QGraphicsItem* parent = 0);
            virtual ~SizeGripItem();
    
        private:
            void doResize();
            QRectF rect_;
            Resizer* resizer_;
    };
    

2 个答案:

答案 0 :(得分:4)

Resizer是对broken(函数对象)的polymorphic functor次尝试。在C ++ 11之前,这样的习惯用法很有用。它被打破了,因为没有虚拟析构函数,这些函子是没用的。它应该看起来如下:

class Resizer {
public:
  virtual void operator()(QGraphicsItem* item, const QRectF& rect) = 0;
  virtual ~Resizer() {}
};

此类对象可以调用:

void invokeResizer(Resizer * resizer, QGraphicsItem * item, const QRectF & rect) {
  (*resizer)(item, rect);
}

以上将在operator()(QGraphicsItem*,const QRectF&)对象上执行方法resizer

在现代代码中,应该使用std::function<void(QGraphicsItem*, const QRectF &)>来代替此类黑客。

答案 1 :(得分:3)

关于第2点,请考虑以下这一行:

(*resizer_)(parentItem(), rect_);

resizer_可能是指向未知类型T的对象的指针,因此*resizer是对同一类型T的对象的引用。
如果它有operator()的定义,它接受两个具有类型(我说)decltype(parentItem())decltype(rect_)的参数,则可以在示例中调用它。 换句话说,它相当于:

resizer_->operator()(parentItem(), rect_);

根本不会修改resizer_的值。

  

有人可以提供有关此运算符为何必要或有用的信息吗?

嗯,这主要取决于背景及其旨在解决的实际问题 从一行代码中很难说出来 如果你发现它没用,就不要使用它。这就是全部。