我想知道是否有人可以向我解释这个宏。
#define Q_DECLARE_PRIVATE(Class) \
inline Class##Private* d_func() { return reinterpret_cast<Class##Private
*>(d_ptr); } \
inline const Class##Private* d_func() const { return reinterpret_cast<const
Class##Private *>(d_ptr); } \
friend class Class##Private;
我有一个使用QT的应用程序,它在以下代码段的最后一行崩溃并出现访问冲突异常。
class Q_GUI_EXPORT QWidget : public QObject, public QPaintDevice
{
Q_OBJECT
Q_DECLARE_PRIVATE(QWidget)
什么可以导致最后一行的空指针操作?
答案 0 :(得分:3)
编译器可以最好地解释它:
g++ -E foo.cc
将在通过预处理器后将foo.cc放入stdout。它可以让你看到编译器看到的内容(特别是使用标记粘贴)通常不太明显。
答案 1 :(得分:1)
您的this
指针是NULL
吗?所有代码都为d_ptr
类成员生成访问函数。
答案 2 :(得分:1)
宏通过声明指向私有实现类的指针来实现Pimpl习语。 ##
垃圾正在使用预处理程序catenation运算符为私有类创建名称。
如果检索d_ptr
成员导致NULL访问,则调用者必须执行NULL->d_func()
。寻找并调试调用者。
答案 3 :(得分:1)
从Windows标题:
#define DECLARE_HANDLE(name) struct name##__ {int unused;} typedef name##__* name;
用法:
DECLARE_HANDLE(YourHandeType); // Just any name, this isn't any type
将新结构创建为:
struct YourHandleType__
{
int unused;
};
typedef YourHandleType__ * YourHandleType;
其中YourHandleType
是YourHandleType__
预处理器将使用标记化器操作符##
来创建全名,C / C ++编译器将使用该名称。在这种情况下,DECLARE_HANDLE
可以创建对调用者不透明的不同类型,并且仍然在不同句柄之间提供“无转换”。