用户定义的 Copy ctor 和 copy-ctors 进一步向下链编译器错误?程序员脑筋急转弯?

Posted

技术标签:

【中文标题】用户定义的 Copy ctor 和 copy-ctors 进一步向下链编译器错误?程序员脑筋急转弯?【英文标题】:user defined Copy ctor, and copy-ctors further down the chain - compiler bug ? programmers brainbug? 【发布时间】:2010-03-08 07:52:49 【问题描述】:

我有一个小问题,我不确定这是编译器错误,还是我的愚蠢。 我有这个结构:

struct BulletFXData

 int time_next_fx_counter;
 int next_fx_steps;
 Particle particles[2];//this is the interesting one
 ParticleManager::ParticleId particle_id[2];
;

成员“Particleparticle[2]”中有一种自制的 smart-ptr(资源计数纹理类)。这个智能指针有一个默认的构造函数,它将 ptr 初始化为 0(但这并不重要)

我还有另一个结构,包含 BulletFXData 结构:

struct BulletFX

 BulletFXData     data;
 BulletFXRenderFunPtr   render_fun_ptr;
 BulletFXUpdateFunPtr   update_fun_ptr;
 BulletFXExplosionFunPtr  explode_fun_ptr;
 BulletFXLifetimeOverFunPtr  lifetime_over_fun_ptr;

 BulletFX( BulletFXData     data,
    BulletFXRenderFunPtr   render_fun_ptr,
    BulletFXUpdateFunPtr   update_fun_ptr,
    BulletFXExplosionFunPtr  explode_fun_ptr,
    BulletFXLifetimeOverFunPtr  lifetime_over_fun_ptr)
 :data(data),
 render_fun_ptr(render_fun_ptr),
 update_fun_ptr(update_fun_ptr),
 explode_fun_ptr(explode_fun_ptr),
 lifetime_over_fun_ptr(lifetime_over_fun_ptr)
 
 
/*
 //USER DEFINED copy-ctor. if it's defined things go crazy
     BulletFX(const BulletFX& rhs)
     :data(data),//this line of code seems to do a plain memory-copy without calling the right ctors
     render_fun_ptr(render_fun_ptr),
     update_fun_ptr(update_fun_ptr),
     explode_fun_ptr(explode_fun_ptr),
     lifetime_over_fun_ptr(lifetime_over_fun_ptr)
     
     
    */
    ;

如果我使用用户定义的 copy-ctor,我的智能指针类会发疯,似乎调用 CopyCtor / 赋值运算符没有按应有的方式调用。 那么 - 这一切都有意义吗?似乎我自己的 struct BulletFX 的 copy-ctor 应该完全按照编译器生成的方式执行,但它似乎忘记在链中调用正确的构造函数。 编译器错误?我傻吗?

对不起,大代码,一些小例子也可以说明。但是你们经常要求真正的代码,很好 - 这里是:D

编辑:更多信息:

typedef ParticleId unsigned int; 

粒子没有用户定义的复制器,但有一个类型的成员:

Particle

    ....
    Resource<Texture>  tex_res;
    ...

Resource 是一个智能指针类,并且定义了所有 ctor(也是赋值运算符) 并且似乎 Resource 是按位复制的。

编辑: henrik 解决了它... data(data) 当然是愚蠢的!它当然应该是 rhs.data !!! 抱歉,代码量很大,其中有一个很小的错误!!! (猜你不应该在凌晨 1 点编码:D)

【问题讨论】:

...您使用的是哪个 C++ 编译器?此外,发布 complete 示例可以让其他人自己编译和尝试。请看:sscce.org 你需要展示Particle类或者至少复制构造函数是如何定义的。 :data(data) 应该做什么?您是说 :data(rhs.data) 吗? 在 :data(data) 中,c++ 标准说第一个数据指的是类数据成员,第二个数据指的是参数列表(正如人们所希望的那样)。然而,我不喜欢它。也许你的编译器也不喜欢它? @Jan:这是一个通用构造函数,但复制构造函数中唯一的参数是rhs 【参考方案1】:
:data(data)

这是有问题的。这是因为您的 BulletFXData 结构没有自己的 copy-ctor。你需要定义一个。

【讨论】:

那是代码不完整的问题,你永远无法知道。如果ParticleParticleManager::ParticleId 都正确,那应该不是问题(生成的复制构造函数应该调用适当的用户定义的内部类型的复制构造函数) 所以这意味着,“memcpy”被称为(可以这么说)数据,因为我想念copyctor?并且链下的所有复制者也被忽略了? 不,生成的复制构造函数将调用每个属性的复制构造函数(如果它们存在)。 struct X std::string s; ; X x1 = "Hi"; X x2 = x1;最后一句会调用字符串构造函数将x1.s复制到x2.s中。 @J.Colmsee:C++ 不使用 memcpy。见这里:***.com/questions/1810163/…【参考方案2】:

我突然想到了两件事:

    这是编译器错误吗 不,这绝不是编译器错误。二十年来,我见过无数的抱怨, “它一定是一个编译器错误”只有一个曾经被证明是一个错误,并且那样 回到 gcc 2.95(现在 gcc 非常稳定(就像开发工作室一样))' 我构建了自己的智能指针。 这是一个很好的概念和很好的学习体验。但这要困难得多 比你想象的要正确。特别是当您似乎遇到问题时 复制构造函数

这是错误的结构是使用自身作为要复制的对象来复制构造的。因此,您将随机数据复制到自身中。

:查看 cmets 以了解您应该使用什么作为参数。

//USER DEFINED copy-ctor. if it's defined things go crazy
 BulletFX(const BulletFX& rhs)
 :data(data),                                   // rhs.data
 render_fun_ptr(render_fun_ptr),                // rhs.render_fun_ptr
 update_fun_ptr(update_fun_ptr),                // rhs.update_fun_ptr
 explode_fun_ptr(explode_fun_ptr),              // rhs.explode_fun_ptr
 lifetime_over_fun_ptr(lifetime_over_fun_ptr)   // rhs.lifetime_over_fun_ptr
 
 

当然,此时您也可以使用编译器生成的复制构造函数版本,因为这正是它正在做的事情。

【讨论】:

是的,我知道 - 愚蠢的复制和粘贴错误。通常我确实知道这些东西:D 关于“滚动我自己的”智能指针:它不仅仅是一个智能指针 - 它是一个使用智能指针逻辑的资源类,但也链接到它的管理器。不能使用普通的智能指针(比如 boost)

以上是关于用户定义的 Copy ctor 和 copy-ctors 进一步向下链编译器错误?程序员脑筋急转弯?的主要内容,如果未能解决你的问题,请参考以下文章

删除copy-ctor和copy-assignment - public、private还是protected?

boost::filesystem::directory_iterator copy-ctor 隐式删除

普通 ctor(或 dtor)和用户定义的空 ctor(或 dtor)有啥区别

当使用 operator=() 时使用 copy-ctor 的 C++ - 这究竟是如何工作的?

std::any 用于仅移动模板,其中 copy-ctor 内的 static_assert 等于编译错误,但为啥呢?

自动生成默认/复制/移动 ctor 和复制/移动赋值运算符的条件?