【问题标题】:C++ Overloading Operator, dereference referenceC++ 重载运算符,取消引用参考
【发布时间】:2014-05-27 04:33:18
【问题描述】:

我在整个项目/类中继承了这个小实用程序类(模板化)。

这个想法是它允许轻松地将各种成员打包进出类实例(对于网络等,并不完全重要)

我得到的如下

    template<typename T>
    struct Packable
        /**
         * Packs a <class T> into a Packet (Packet << T)
         * Required for chaining packet packing
         *************************************************/
        virtual sf::Packet& operator <<(sf::Packet& packet) = 0; // Work-horse, must be defined by child-class

        friend sf::Packet& operator <<(sf::Packet& packet, const T *t)
        {
            // Call the actual one, but basically do nothing...
            return packet << *t;
        }

        friend sf::Packet& operator <<(sf::Packet& packet, const T &t)
        {
            // Call the actual one, but basically do nothing...
            return packet << &t;
        }

        friend sf::Packet& operator <<(sf::Packet& packet, T *t)
        {
            // Call the actual one, but basically do nothing...
            return packet << *t;
        }

        friend sf::Packet& operator <<(sf::Packet& packet, T &t)
        {
            // Call the actual one, but basically do nothing...
            return packet << &t;
        }
    };

我想要做的,简而言之,就是让它只需要在子类中指定/充实一种方法(用“虚拟”词表示)。

我想要的是提供采用各种形式的类的其他方法,并根据需要取消引用它们以使用编译类时将存在的虚拟方法。

问题是我似乎创建了一些无限循环。

        friend sf::Packet& operator <<(sf::Packet& packet, T &t)
        {
            // Call the actual one, but basically do nothing...
            return packet << &t;
        }

只是一遍又一遍地调用自己。如何取消引用对其对象的引用?

【问题讨论】:

  • @RakibulHasan,&amp;tt所指对象的地址。
  • 你有一个没有结束条件的递归定义。您应该实现其中一个运算符。
  • @RakibulHasan 奥利? See it live.
  • @MohitJain 是的...正如我在 OP 中所述,我有一个递归定义。问题是,我该如何解决这个问题?我不能将
  • 所有这些友元函数与抽象 Packable 运算符 anything 是 Packable 或其中的派生;只是一堆使用sf:Packets 操作的友元方法。

标签: c++ templates inheritance operator-overloading dereference


【解决方案1】:

operator &lt;&lt; 有 4 个重载,它们相互依赖。

  1. const T *,取决于 2
  2. const T&,取决于 1
  3. T *,取决于 4
  4. T&,取决于 3

所以它引起了无休止的回避。您应该至少将其中一个实现为independent functionality,然后其余的都依赖于此。

如下图即可

template<typename T>
struct Packable
    /**
     * Packs a <class T> into a Packet (Packet << T)
     * Required for chaining packet packing
     *************************************************/
    virtual sf::Packet& operator <<(sf::Packet& packet) = 0; // Work-horse, must be defined by child-class

    friend sf::Packet& operator <<(sf::Packet& packet, const T *t)
    {
        // Call the actual one, but basically do nothing...
        return packet << *t;
    }

    friend sf::Packet& operator <<(sf::Packet& packet, const T &t)
    {
        // Call the actual one, but basically do nothing...
        //return packet << &t;

        // Serialize the contents into packet stream
        t.serialize(packet);
        return packet;
    }

    friend sf::Packet& operator <<(sf::Packet& packet, T *t)
    {
        // Call the actual one, but basically do nothing...
        return packet << const_cast<const T*>(t);
    }

    friend sf::Packet& operator <<(sf::Packet& packet, T &t)
    {
        // Call the actual one, but basically do nothing...
        return packet << &t;
    }
};

这个函数serialize应该在每个T类型的类中实现,否则你会看到编译时错误。

【讨论】:

  • 我希望虚拟方法 virtual sf::Packet&amp; operator &lt;&lt;(sf::Packet&amp; packet) = 0; 成为执行序列化的主力(见评论)。我希望 T 类的所有其他形式都使用该方法。所以如果它是一个指针,取消引用指针并调用它的方法。如果它是一个引用,则取消引用该引用并调用它的方法。这有意义吗?
猜你喜欢
  • 1970-01-01
  • 2018-08-04
  • 1970-01-01
  • 2013-12-25
  • 2021-08-01
  • 2016-10-16
  • 1970-01-01
  • 1970-01-01
  • 2016-08-22
相关资源
最近更新 更多