2011-12-23 76 views
0

最近,由于基类和派生类没有被编译,因此类大小发生变化,所以我一直面临着很少的崩溃。让我给你一个简单的例子。我有一个基类,'BaseClass'出现在Base.dll中,并且我继承了该类并创建了Derived.dll中存在的DerivedClass。每当BaseClass大小发生变化时,应重新编译Derived.dll。但是,找到所有依赖的二进制文件并不总是可能的,有时候人们会错过一些依赖的二进制文件。在这些情况下,我们会遇到非常难以调试的神秘崩溃。有什么办法可以缩小这些问题吗?换句话说,什么线索会让你在这个方向上思考?由于基类大小变化而导致的调试崩溃

编辑1:更多细节。请假设有多个基类,例如base1,base2,base3等,每个基类都是在单独的dll中派生的。 derived1.dll,derived2.dll和derived3.dll。没有必要为一个基类中的大小更改编译所有其他项目。另外,制作依赖不是一种选择,这就是我们经常遇到这个问题的原因。

+1

对“BaseClass”定义的更改应触发对“DerivedClass”及其依赖项的重新编译。为什么不发生这种情况? – 2011-12-23 07:06:23

回答

0

除了重新编译之外,没有任何傻瓜证明选项。如果发现哪些类是从您的class BaseClass派生出来的,那么可以通过以下方式解决。

class FinalLock { 
    FinalLock() {} 
    friend class BaseClass; 
}; 

无论何时更改BaseClass大小,就如下:

class BaseClass : virtual FinalLock { 
    ... 
}; 

,并重新编译整个项目。无论哪个类从BaseClass派生将导致编译器错误(实际上,类的实例化将导致错误)。

这告诉你哪些类依赖于BaseClass。这个练习只需要一次。然后您可以标记所有的相关代码。

完成后删除这些额外的代码。用C++ 11中,上述技术可制成仍然更容易:

final class BaseClass { 
^^^^^ 
}; 
0

方法之一将是固定以使所有从属模块是否重新编译的依赖关系。这可能是共享库的一个麻烦,但看看它是否不能直接修复。

方法二将始终“重建所有”。或者总是删除obj目录中的所有内容并构建。

方法三将添加一些调试模式代码,用于检查对象的大小并将它们与API边界上的新调用进行比较,该边界返回对象的大小。