我在标题中的命名空间中定义了一个类,如下所示
#ifndef _c1_
#define _c1_
namespace classspace
{
class Aclass;
}
class Aclass
{
//body
};
#endif _c1_
我将此标头添加到main.cpp并在main()中创建了一个对象,但其返回的错误为undefined class 'classspace::Aclass'
它是我的主要
void main()
{
classspace::Aclass b;
}
当我将类定义为
时class classspace::Aclass
{
//body
};
错误已解决。 我在Qt mainwindow文件中看到了第一种方法:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
正在运行,没有任何错误。 在第一种方法中我的错误是什么?
答案 0 :(得分:7)
类定义必须位于您声明该类的同一名称空间中。
对于Qt示例,在命名空间之外声明的MainWindow不是同一个类。
它使用Pimpl idiom。在名称空间中声明的MainWindow类用作在外部声明的MainWindow类中的成员,并使用其名称空间进行限定:
Ui::MainWindow* ui;
此类的定义放在其他位置(在不同的.cpp文件中),它应位于Ui
命名空间中,或者带有前缀为命名空间的定义。
答案 1 :(得分:4)
namespace classspace
{
class Aclass;
}
这在名称空间内声明了一个类。
class Aclass
{
//body
};
这声明并定义了一个在全局命名空间中具有相同名称的不同的类
class classspace::Aclass
{
//body
};
这定义了您先前在命名空间中声明的类。
void main()
{
classspace::Aclass b;
}
这会尝试实例化名称空间中声明的类。如果该类尚未定义(仅声明),则不完整且无法实例化。
Qt示例涉及两个类:全局命名空间中的Ui::MainWindow
和MainWindow
。 Ui
中的那个只被声明,所以标题中不完整。你可以用它做各种各样的事情,比如声明指向它的指针,但是你无法实例化它。
据推测,有一个单独的源文件定义了Ui
类,实例化了一个,并将指针设置为指向它。
顺便说一句,你不应该使用reserved names作为包含守卫,或其他任何东西。此外,main
的返回类型必须为int
。
答案 2 :(得分:0)
namespace classspace
{
class Aclass;
}
class Aclass
{
//body
};
这两个类是两个不同的类(具有相同的名称)。
您正在使用尚未定义的classspace::Aclass
。在namespce中添加正文:
namespace classspace
{
class Aclass
{
//body
};
}
答案 3 :(得分:0)
您在命名空间中声明了该类,但在命名空间之外定义它。所以宣言是:
classspace::Aclass
但该定义定义了以下的实现:
::Aclass
命名空间应该与声明和定义匹配。
答案 4 :(得分:0)
命名空间本质上是包。在您的Qt示例中,该类是向前声明的。使用命名空间的一种方法如下:
namespace MyNamespace
{
class MyClass
{
};
}
如果你想像第一个例子那样做,那么你必须转发声明它。例如,
namespace MyNamespace
{
class MyClass;
}
class MyClass
{
//body
};
答案 5 :(得分:0)
想象
namespace foo
{
class AClass;
}
namespace goo
{
class AClass;
}
class AClass
{
}
int main()
{
AClass myClass;
}
我们使用哪一个? foo
或goo
?
您必须通过调用具有命名空间名称的所有AClass使用来指定,即foo::AClass
,或者将所有用途放在
namespace foo
{
}