就在我认为我有指针的时候,看起来我仍然有点困惑。我正在写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&)
我该如何解决这个问题?
答案 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.root
是QtreeNode**
,因为您使用*
取消引用该表达式,并且该表达式明显产生QtreeNode*
。无论是那个还是root
做了一些非常时髦的运算符重载。无论如何,您将QTreeNode*
传递给期望QTreeNode&
的函数;如果**source.root
需要source.root
类型,则应使用QtreeNode**
或(更好)重新评估。 (我的猜测是没有。)
编辑:我同意其他人的观点,即惯用的C ++方法是创建一个复制构造函数。但是,我想我的方法是帮助解释为什么它不编译。我想帮助你弥合概念上的差距,用更多C风格的指针操作进行练习会很好......
答案 1 :(得分:0)
如果传入指针而不是
,则不需要返回QtreeNoderoot=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调用的实际参数来解决问题。