manière de définir la classe dans un espace de noms

J’ai défini une classe dans un espace de noms dans un en-tête comme suit

#ifndef _c1_ #define _c1_ namespace classspace { class Aclass; } class Aclass { //body }; #endif _c1_ 

J’ai ajouté cet en-tête à main.cpp et fait un object dans main () mais son erreur de retour est celle de la undefined class 'classspace::Aclass'

 void main() { classspace::Aclass b; } 

quand j’ai défini la classe comme

 class classspace::Aclass { //body }; 

erreur résolue. J’ai vu dans Qt fichier mainwindow en utilisant la première approche:

 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include  namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H 

travaille sans erreur. Quelle est mon erreur dans la première approche?

La définition de la classe doit figurer dans le même espace de noms que celui dans lequel vous avez déclaré la classe.

Comme pour l’exemple Qt, la MainWindow déclarée en dehors de l’espace de noms n’est pas la même classe .

Il utilise l’ idiome Pimpl . La classe MainWindow déclarée dans l’espace de noms est utilisée en tant que membre dans la classe MainWindow déclarée à l’extérieur et est qualifiée avec son espace de noms:

 Ui::MainWindow* ui; 

La définition de cette classe est placée ailleurs (dans un fichier .cpp différent) où elle devrait se trouver dans l’espace de noms Ui , ou avec des définitions préfixées par cet espace.

 namespace classspace { class Aclass; } 

Cela déclare une classe à l’intérieur d’un espace de noms.

 class Aclass { //body }; 

Cela déclare et définit une classe différente portant le même nom dans l’espace de noms global.

 class classspace::Aclass { //body }; 

Ceci définit la classe que vous avez précédemment déclarée dans l’espace de noms.

 void main() { classspace::Aclass b; } 

Ceci tente d’instancier la classe déclarée dans l’espace de noms. Si cette classe n’a pas été définie (seulement déclarée), elle est incomplète et ne peut pas être instanciée.

L’exemple Qt implique deux classes: Ui::MainWindow et MainWindow dans l’espace de noms global. Celui dans Ui a seulement été déclaré, il est donc incomplet dans l’en-tête. Vous pouvez faire diverses choses avec elle, comme déclarer un pointeur sur celle-ci, mais vous ne pouvez pas l’instancier.

Vraisemblablement, il existe un fichier source séparé qui définit la classe Ui , en instancie un et positionne le pointeur sur celle-ci.

En passant, vous ne devriez pas utiliser de noms réservés pour vos gardes include, ni pour quoi que ce soit d’autre. De plus, le type de retour de main doit être int .

 namespace classspace { class Aclass; } class Aclass { //body }; 

Ces deux classes sont deux classes différentes (avec le même nom).

Vous utilisez classspace::Aclass qui n’a pas encore défini. Ajoutez le corps dans le namespce:

 namespace classspace { class Aclass { //body }; } 

Vous déclarez la classe dans l’espace de noms mais vous la définissez en dehors de celui-ci. La déclaration est donc:

 classspace::Aclass 

mais la définition définit l’implémentation pour:

 ::Aclass 

Les espaces de noms doivent correspondre pour la déclaration et la définition.

Les espaces de noms sont essentiellement des packages. Dans votre exemple Qt, la classe est déclarée en avant. Une façon d’utiliser les espaces de noms est la suivante:

 namespace MyNamespace { class MyClass { }; } 

Si vous voulez le faire comme votre premier exemple, vous devez alors le déclarer. Par exemple,

 namespace MyNamespace { class MyClass; } class MyClass { //body }; 

Imaginer

 namespace foo { class AClass; } namespace goo { class AClass; } class AClass { } int main() { AClass myClass; } 

Lequel utilisons-nous? foo ou goo ?

Vous devez spécifier, soit en appelant toutes les utilisations de AClass avec le nom d’espace de nom, c.-à-d. foo::AClass , ou en plaçant toutes les utilisations à

 namespace foo { }