编辑遵循决议,这已被大量编辑,以转储不相关的细节和解释真正的问题.
我最近在一些旧代码中发现了一个问题.特定的代码很少使用,并且没有足够的单元测试(当我发现问题时我添加了更多).我最近才停止使用Visual C++ 2003,并且VC++ 9中没有显示症状,仅在MinGW GCC 4.4.0中显示.并且只发布版本.一旦我添加了任何跟踪代码,症状就会消失.你不喜欢那些吗?
无论如何,事实证明,在所有情况下都没有调用复制构造函数和赋值运算符重载.结果,数据结构变得不一致.大部分时间我都在匆匆忙忙.
我通过VC++ 9调试器逐步查看了这个问题,即使VC++ 9版本没有显示出症状.所以,至少有两个编译器表现相同,即使症状没有表现出来 - 一个公平的暗示,让我不知不觉的行为符合标准,而且我一直依赖于旧的非标准行为.
那么......在什么情况下,继承基类的构造函数等无法被调用?
FWIW,问题代码是导致这个问题的库的一部分.
解析度
有两个单独的问题 - 复制构造和重载分配.
在最近的"命名"变体中,复制构造问题被证明是众所周知的返回值优化问题.涉及的对象是指向多路树叶节点的"游标"(如迭代器).为了确保维护它们,每个叶节点都保留一个引用它的游标的链接列表.
游标是一个非常轻量级的类 - 叶节点指针,节点中的下标和维护列表的下一个指针.需要显式构造/销毁/分配的唯一原因是维护游标列表的副作用.
因为类是如此轻量级,并且因为很少有多个游标(特别是很少有一个或两个游标指向特定的叶节点),我有时会使用按值传递和按值返回.后者似乎是问题所在.
更改副本构造函数实现意外地绕过了这个问题 - 我得到的印象(未经证实)对于发布版本,MinGW GCC和VC++仍然试图避免绕过具有副作用的复制构造函数,但是会遗漏某些副作用.
第二个问题 - 分配过载.我认为,这对我来说是一个古老的愚蠢错误,如果我在大致相同的时间没有复制构造函数问题,我会更快地弄清楚它.
赋值重载是通过两层继承继承的,其中包含一些模板,隐私和依赖类型的复杂性.中间或派生类都没有超越它.在这种特殊情况下,这种有意义(以错误的方式) - 派生类不添加任何成员数据,它只是将模板参数提供给基础并添加一些方法.但是如果标准有特殊情况"我没有添加任何成员数据",我会感到非常惊讶.
对于较旧的编译器,我认为我正在使用隐式转换规则,允许调用基类赋值操作.我不想尝试追踪行为改变的确切原因 - 关键是我因为编写一些杂乱而奇怪的结构化代码而受到惩罚.
| 归档时间: |
|
| 查看次数: |
242 次 |
| 最近记录: |