【发布时间】:2016-04-13 04:25:35
【问题描述】:
我正在上课 Place 使用这样的方法:
class Place{
protected:
Keypoint* _kp;
Place() {
Keypoint* kp = new Keypoint();
_kp = kp;
};
Place(const Place& cSource){
delete _kp;
_kp = cSource.makePointer();
}
virtual ~Place(){
delete _kp;
}
virtual Keypoint* makePointer() const {
return _kp->makePointer();
}
};
因此是构造函数、析构函数和复制方法。
在我的主要操作中,我做了一些像AASS::graphmatch::Place ppp; AASS::graphmatch::Place p2(ppp); 这样简单的事情来尝试复制构造函数,并且我有一个巨大的段错误,valgrind 告诉我在副本中删除后我使用了Conditional jump or move depends on uninitialised value(s)。 Keypoint 中的方法makePointer 执行new 并返回一个指针Keypoint*。
virtual Keypoint* makePointer() const {
Keypoint* d = new Keypoint();
return d;
}
我的理解是每个新的都应该使用 delete 来释放,这就是为什么我在调用 makePointer 之前使用 delete。所以这就是为什么我首先删除 _kp 以释放旧内存,然后将新创建的指针分配给它。
我无法理解为什么我有未初始化的值?
【问题讨论】:
-
当您在复制构造函数中
delete _kp;时,_kp尚未为新对象初始化,因此您正在尝试delete <garbage-ptr> -
这真的是复制构造函数吗?似乎每次都默认创建关键点(除非您使用一些看不见的全局变量)。这似乎违反了
x == y原则…… -
我不确定在这种情况下
x==y原则是什么:S,但我所做的是我有一些从 Keypoint 继承的类并使用 makePointer( )。因此,根据 cSource 类型,我获得了一个 cSource 类的指针,它也是一个 Keypoint。 -
@Malc 评论有点草率,但我的意思是,如果您有一个复制构造函数,您可能希望复制复制构造的对象在某种程度上等于旧对象。假设
Place p {}; Place p2{p}; bool eq = p==p2;,那么 eq 应该为真。您当然可以根据需要定义相等运算符,但在这种情况下,您获得的每个“副本”看起来都与默认构造的对象相同,在我看来,这并不是一个副本。特别是您希望f(p)和f(p2)给出相同的答案,如果您在复制构建之前对p进行了更改,这将很难。 -
@patrik 我明白你的意思了:)!在这里很好,因为每个关键点一旦创建就无法更改。它们包含诸如类型之类的东西,该类型由相同关键点相同的字符串或相同关键点相同的颜色定义。因此,在我的应用程序中,一旦创建,关键点就永远无法更改。但是感谢您指出它,因为如果我改变它,我就不会意识到它,我可能会犯错误:)。
标签: c++ pointers copy-constructor delete-operator