带指针的函数

时间:2011-04-01 17:17:25

标签: c++ pointers

就在我认为我有指针的时候,看起来我仍然有点困惑。我正在写operator = overload,所以我想释放内存然后分配新的。我正在处理一个Quad树类,其中每个树都有一个指向根节点的指针,一个根节点有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&)

我该如何解决这个问题?

5 个答案:

答案 0 :(得分:2)

除去nodeCopier的论点,这部分对我来说不合适......

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

nodeCopier返回QNode(基于您的return语句可以从QtreeNode隐式转换)但是从第一行我们可以将其分配给QtreeNode* 1}}。或者更普遍地说,你正在将非指针数量分配到指针中。

看起来你可能想要这样做:

*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.rootQtreeNode**,因为您使用*取消引用该表达式,并且该表达式明显产生QtreeNode*。无论是那个还是root做了一些非常时髦的运算符重载。无论如何,您将QTreeNode*传递给期望QTreeNode&的函数;如果**source.root需要source.root类型,则应使用QtreeNode**或(更好)重新评估。 (我的猜测是没有。)

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

答案 1 :(得分:0)

如果传入指针而不是

,则不需要返回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
}

希望这有帮助,

埃蒙

答案 2 :(得分:0)

你在一个包含的类上提到了operator = overload 指针。所以让我们上升一级,看看它是什么:我怀疑 你真正需要的是一个复制构造函数(第一个),然后使用 交换成语。类似的东西:

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 );
}

您绝对不想做的是之前删除现有节点 你已成功复制了新树;这是一个肯定的接受 未定义的行为---通常以双删除的形式出现。

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

答案 3 :(得分:0)

看起来海报的问题是实施副本分配(operator =)。我建议您在复制构造函数(即复制和交换)方面实现operator =。看看this example in SO。看看operator =是如何在那里实现的。

如果您已经实现了复制构造函数,那么这将非常适合operator =,因此您不需要为了复制赋值而实现此“nodeCopier”。

答案 4 :(得分:0)

在指针上指定“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调用的实际参数来解决问题。