【问题标题】:Functions with pointers带指针的函数
【发布时间】:2011-04-01 17:17:24
【问题描述】:

就在我以为我的指针向下时,看起来我还是有点困惑。我正在写 operator= 重载,所以我想释放内存然后分配新的。我正在处理一个四叉树类,其中每棵树都有一个指向根节点的指针,一个根节点有 4 个指向 4 个子节点的指针,每个节点都有 4 个子节点。所以 operator= 应该只复制另一棵树的根并返回它。所以在解除分配等之后,我开始想要分配新的内存和分配。所以我这样做:

root=new QtreeNode;
root=nodeCopier(*(source.root));

这是我的 nodeCopier 签名:

QNode nodeCopier(const QtreeNode & n) {
    QtreeNode tempNode;

    //stuff

     return tempNode;
}

然后我得到这个错误错误:

no matching function for call to
    Qtree::nodeCopier(Qtree::QtreeNode* const&)
    qtree.h:92: note: candidates are: Qtree::QtreeNode Quadtree::nodeCopier(const Qtree::QtreeNode&)

我该如何解决这个问题?

【问题讨论】:

  • 你能发布你的班级声明QtreeNode吗?

标签: c++ pointers


【解决方案1】:

去掉nodeCopier的论点,这部分对我来说看起来不对..

root=new QtreeNode;
root=nodeCopier( /* ... */ );

nodeCopier 返回QNode(基于您的return 语句可以从QtreeNode 隐式转换)但是从第一行我们可以将它分配给QtreeNode*。或者更一般地说,您将非指针数量分配给指针。

看起来你可能想做:

*root = nodeCopier( /* ... */ );

根据此处的第二行和错误消息,我可以看到第二个问题。

root=nodeCopier(*(source.root));

Qtree::nodeCopier(Qtree::QtreeNode* const&)
qtree.h:92: note: candidates are:
   Qtree::QtreeNode Quadtree::nodeCopier(const Qtree::QtreeNode&)

基于此,source.root 看起来像 QtreeNode**,因为您使用 * 取消引用它并且该表达式显然产生了 QtreeNode*。无论是那个还是root 都做了一些非常时髦的运算符重载。无论如何,您将QTreeNode* 传递给期望QTreeNode& 的函数;您应该使用**source.root 或(更好)重新评估source.root 是否需要为QtreeNode** 类型。 (我的猜测是没有。)

编辑: 我同意其他人所说的惯用 C++ 方法是创建一个复制构造函数。但是我想我的方法是帮助解释为什么它不能编译。我想为了帮助您弥合概念上的差距,最好通过更多 C 风格的指针操作进行一些练习...

【讨论】:

    【解决方案2】:

    如果你传入一个指针,你不需要返回一个 QtreeNode,你应该这样做

    root=new QtreeNode();                       //declare a new QtreeNode
    root=nodeCopier(&(source.root));            //pass a pointer to root into nodeCopier
    
    void nodeCopier(const QtreeNode* n) {       
        QtreeNode tempNode = new QtreeNode();   //declare a local QtreeNode
    
        //stuff
    
       *n = tempNode;                           //dereference root pointer and assign tempnode
       delete(tempNode);                        //Delete tempNode to prevent memory Leak
    }
    

    希望对你有帮助,

    埃蒙

    【讨论】:

    • 这里仍然出现错误。 n 不是指针,那你为什么要在最后一行取消引用呢?
    • 不好意思,看我最新的编辑,需要在函数参数中放*来传入一个指针,调用函数时使用&。 * 在变量声明之后表示将此变量声明为指针,* 在变量名之前表示取消引用此指针,& 表示使用传递此变量的内存位置
    【解决方案3】:

    您在包含的类上提到了 operator= 重载 指针。所以让我们上一层,看看它是什么:我怀疑 你真正需要的是一个复制构造函数(首先),然后使用 交换成语。比如:

    QtreeNode::QtreeNode( QtreeNode const& other )
        : north( other.north == NULL ? NULL : new QtreeNode( *other.north ) )
        , east( other.east == NULL ? NULL : new QtreeNode( *other.east) )
        , south( other.south == NULL ? NULL : new QtreeNode( *other.south) )
        , west( other.west == NULL ? NULL : new QtreeNode( *other.west) )
    {
    }
    
    QtreeNode& QtreeNode::operator=( QtreeNode const& other )
    {
        QtreeNode tmp( other );
        swap( tmp );
        return *this;
    }
    
    void QtreeNode::swap( QtreeNode& other )
    {
        std::swap( north, other.north );
        std::swap( east, other.east );
        std::swap( south, other.south );
        std::swap( west, other.west );
    }
    

    您绝对不想做的是删除之前的现有节点 您已成功复制新树;这是肯定的 未定义的行为——通常以双重删除的形式。

    而且你不需要复制的特殊功能;复制构造函数 以上是递归的,会为你处理一切。

    【讨论】:

      【解决方案4】:

      看起来发帖人的问题是实现复制分配(operator=)。我建议您根据复制构造函数来实现您的 operator=,即复制和交换。看看this example in SO。看看 operator= 是如何在那里实现的。

      如果您已经实现了复制构造函数,这几乎可以免费为您提供 operator=,因此您不需要仅仅为了复制分配而实现这个“nodeCopier”。

      【讨论】:

        【解决方案5】:

        当在指针上指定“const”时,它可以应用于一两件事。指针可以是常量(即指针包含的地址不能改变),或者该地址指向的值可以是常量,或者两者都可以是常量。请参阅here 进行讨论。

        const QtreeNode *       p1 = <value>;  // non-constant pointer to     constant value
              QtreeNode * const p2 = <value>;  //     constant pointer to non-constant value
        const QtreeNode * const p3 = <value>;  //     constant pointer to     constant value
        

        如您的问题所示,nodeCopier 函数引用了一个常量 QtreeNode。从错误消息中我们可以看到编译器正在寻找一个 nodeCopier,它引用一个指向 QtreeNode 的常量指针

        Qtree::nodeCopier(Qtree::QtreeNode* const&)
        

        换句话说,*(source.root) 的类型与 nodeCopier 函数的形式参数的类型不匹配。您可以通过更改 nodeCopier 的定义或更改传递给 nodeCopier 调用的实际参数来解决此问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-05-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多