2010-08-06 14 views
1

Je dois appeler les propriétés et les fonctions d'un objet d'une classe différente.C++ - Comment appeler la classe/l'objet créateur

L'idée passe 'this' comme paramètre au constructeur de l'autre classe. .: par exemple

instance = ClassName(this); 

Et puis faire:

ParentClass parentInstance; 
ClassName::ClassName(MainApp _instance){ 
    parentInstance = _instance; 
} 

Cependant, mon compilateur dit que ParentClass ne nomme pas un type. Des idées? De même, devrais-je utiliser un pointeur pour économiser de la mémoire? Comment?

Merci d'avance.


MISE À JOUR:

Ok, désolé pour le retard. Ici, il va le code réel. D'abord, une classe simple.

classe du jeu:

fichier d'en-tête

#ifndef _GAME 
#define _GAME 

#include "ofMain.h" 

class Game{ 

public: 
    Game(); 
    ~Game(); 

    void hi(); 
}; 

#endif 

fichier cpp:

#include "Game.h" 
Game::Game(){} 
Game::~Game(){} 

void Game::hi(){ 
cout << "hi, I'm game! " << endl; 
} 

Puis, à partir MainApp je crée l'objet: - code approprié sur fichier d'en-tête:

#ifndef _MAIN_APP 
#define _MAIN_APP 

#include "ofMain.h" 
#include "Game.h" 

class MainApp : public ofSimpleApp{ 
public: 
    Game game; 
}; 

#endif 

code approprié sur le fichier cpp:

game = Game(); 
game.hi(); 

Cela fonctionne évidemment que je crée seulement un objet sanglant. Cependant, le problème vient avec la composition.

Je pourrais passer l'application principale comme argument dans le constructeur, je pourrais le passer via game.setParent (this); ... le problème est, je ne peux même pas définir la variable pour stocker la référence à l'application.

Par exemple: (le rendant facile/inefficace sans pointeurs ou quoi que ce soit)

Game.h:

#define _GAME 
#ifndef _GAME 

#include "ofMain.h" 
#include "MainApp.h" 

class Game{ 
MainApp app; 

public: 
    Game(); 
    ~Game(); 

    void hi(); 
}; 
#endif 

Ce retourne un "ne désigne pas un type" erreur et déclarant class MainApp renvoie un « incomplet tapez "erreur

Je suis sûr que je fais quelque chose de stupide.


MISE À JOUR 2:

Le problème avec cette méthode est que je ne peux pas appeler une fonction de l'objet pointu maintenant.

Ceci est le jeu.h:

#ifndef _GAME 
#define _GAME 

#include "ofMain.h" 

class MainApp; 
class Game{ 


public: 
    Game(); 
    Game(MainApp* _app); 
    ~Game(); 

    void hi(); 

    MainApp* app; 
}; 

#endif 

Comme vous le voyez, l'application (de type MainApp) est transmise en tant que paramètre. C'est bien, MainApp existe car c'est la déclaration forward. Cependant, lorsque j'essaie d'appeler l'une des fonctions de l'application, je ne peux pas (erreur de compilation disant Demande de membre appHi dans .... qui est de type non-classe 'MainApp'

MainApp n'est pas inclus dans Game.h mais Game.h est inclus dans MainApp.h.

Idées?

+3

Postez le code actuel. –

+0

Vous devriez probablement jeter un coup d'oeil aux mécanismes de passage d'argument de différence (une brève description j'ai travaillé pour une autre question peut être trouvée [ici] (http://stackoverflow.com/questions/2139224/how-to-pass-objects-to -functions-in-c/2139553 # 2139553)) vous faites actuellement des copies au lieu de stocker des références au parent. En plus de cela, je suis fortement d'accord avec Neil: ** montre le vrai code **. –

Répondre

2

Le problème est que vous avez une référence circulaire - Le jeu inclut MainApp, et MainApp inclut le jeu. Vous avez besoin d'une «déclaration avant», comme dans l'exemple de DeadMG.

Voir here.

+0

Euh, c'était EXACTEMENT le problème que j'avais. Merci beaucoup. Aussi merci pour le reste. :) La plupart des réponses indiquaient la bonne direction. Ma faute pour ne pas poster plus de code avant. – ozke

+0

Le problème est que le compilateur ne peut plus trouver les fonctions de l'application que j'essaie d'appeler car elles ne sont plus fortement typées. erreur: utilisation invalide de type incomplet 'struct MainApp' – ozke

+0

Il restera fortement typé. Mais notez que selon cette autre réponse, vous devrez utiliser un pointeur dans l'une de vos classes - vous ne pouvez pas 'utiliser' une classe tant qu'elle n'est pas définie, donc deux classes ne peuvent pas 's'utiliser'. Mais le compilateur peut gérer un pointeur - ils sont tous les mêmes. – sje397

0

Ce n'est pas comment les choses fonctionnent en C++. Contrairement à javascript, vous ne pouvez pas injecter des méthodes ou des champs en objets existants lors de l'exécution.

+0

Je ne veux pas les injecter, il suffit de les appeler. E.g .: parentInstance.draw(); – ozke

0

Il est appelé composition et est un modèle commun.Il est très efficace à la fois en termes de sémantique et en termes de vitesse d'exécution/empreinte de la mémoire

Votre exemple de code est un peu trop de pseudo-code pour que je le lise correctement. Laissez-moi vous montrer comment c'est fait.

class X; 
class Y { 
    ... 
    void DoSomething(X* x, ... args); 
}; 
class X { 
    Y y; 
    void DoSomething() { 
     y.DoSomething(this, args); 
    } 
}; 
+0

J'ai essayé mais ça dit y a un type incomplet. Y est défini dans un fichier .h/.cpp différent, j'ai inclus cependant. – ozke

+0

@ozke: Y a un type complet si vous incluez la définition complète. Je ne peux pas réparer votre #includes. – Puppy

+0

Merci. Je vais continuer à essayer de trouver où est l'erreur. – ozke

1

Je pense qu'il peut y avoir deux questions:

1) Vous devez déclarer la ParentClass (ig #include son .hpp fichier) avant de l'utiliser

2) L'affectation " parentInstance = _instance "appellera l'opérateur d'assignation, ce que je devine n'est pas ce que vous voulez. Laisser "parentInstance" être un pointeur à la place.

+0

J'inclus le fichier .h et déclare ParentClass (Classe ParentClass) mais j'obtiens cette erreur: h: 40: erreur: le champ 'parentInstance' a le type incomplet – ozke

+0

Je pense que vous avez besoin de poster du code, si vous voulez de l'aide avec la réparation ça ... –

0

Madsen est sur la bonne voie, mais nous avons besoin de plus de code; Quelle est la hiérarchie de classe de ParentClass, ClassName et SaleraApp. Quelles classes sont bases et/ou dervies?

Lorsque vous écrivez: parentInstance = _instance; le compilateur essaiera de générer un constructeur de copie par défaut s'il n'en est pas un. Votre problème peut être que vous essayez de créer un objet de classe dervied à partir d'un pointeur de classe de base.

De plus, "this" est un pointeur.

0

Si tout ce que vous devez faire est d'utiliser des fonctions et des membres de données d'une autre classe, lisez sur le mot-clé friend. Il permettra l'accès aux membres de la classe d'autres classes. MISE À JOUR: Vous pouvez également stocker un pointeur ou une référence sur l'objet auquel vous devez accéder, et créer des accesseurs pour les membres de données et rendre les fonctions publiques ... mais j'ai l'impression que ce n'est pas ce que vous recherchez. .

+0

J'ai tendance à ignorer le clavier ami car je le considère comme un ennemi de l'encapsulation mais, Bien sûr, c'est un choix personnel et un ami peut toujours être utile dans certains scénarios. Merci pour votre réponse :) – ozke