开发者

A problem with object member

开发者 https://www.devze.com 2023-02-24 22:21 出处:网络
I\'ve got a problem in a C++ program that I can\'t solve. I\'m trying to pass an object as a construction parameter of an other but i can\'t figure out how to do this.

I've got a problem in a C++ program that I can't solve. I'm trying to pass an object as a construction parameter of an other but i can't figure out how to do this.

My main is creating a Simulation object. In simulation i'm creating two objects a planete and a modelisation. The thing is, i want to pass the planete object in the modelisation object.

My first object is Simulation.

#include "Simulation.h"
#include "Modelisation.h"
#include "Planete.h"

Planete *Obj;
Modelisation *Model;

Simulation::Simulation (int argc, char **argv)
{
    Obj = new Planete ("Terre", (5.98*pow(10.0,24.0)), 6378.137, 0, 0, 0);
    Model = new Modelisation (argc, argv,"Modelisation",1600 ,1004, 306, 0);
};
Simulation::~Simulation ()
{
    delete Obj;
    delete Model;
};

Modelisation.h

class Modelisation
{
private:
    int hauteur, largeur, x, y;
    int fenetre;
    //Planete ClonePlanete
public:
    Modelisation (int argc, char **argv, char[], int, int, int, int);
    ~Modelisation ();
    static void Dessiner ();
    static void Redessiner (int, int);
    void InitCallBack ();
};

Modelisation.cpp

#include "stdafx.h"
#include "Modelisation.h"
#include "Camera.h"
#include "Planete.h"

Camera *camera;

Modelisation::Modelisation (int argc, char **argv, char nomFenetre [] ,int hauteur, int largeur, int x, int y)
{

    glutInit (&开发者_开发百科amp;argc, argv);
    glutInitDisplayMode (GLUT_SINGLE);
    glutInitWindowSize (hauteur, largeur);
    glutInitWindowPosition (x, y);
    fenetre = glutCreateWindow (nomFenetre);
    camera = new Camera;
//  Planete ClonePlanete = new Planete(planete);  // Basicaly that's what i'm trying to do
};

Modelisation::~Modelisation ()
{
    delete camera;
};

Planete.h

class Planete
{
private:
    std::string nom;
    double masse;
    double diametre;
    struct position { double x, y, z;};
    double x,y,z;

public:
    Planete (std::string nom, double masse, double diametre, double x, double y, double z);
    Planete (const Planete &);
    ~Planete ();
};

Thanks for your help, it will be very appreciated!


You can pass it in by constant reference in the constructor then have a private members that gets initialized like so:

Modelisation(const Planete& planRef) : m_planete(planRef)

Also nifty french variable names ;)

Edit:

There are some interesting design choices here you may want to reconsider global variables in favor of class members, favor smart pointers instead of dynamic allocation and deallocation the traditional way, and consider the relationships your objects have. Your simulation is a prime candidate for composition, your planets could use inheritance and polymorphism as you progress to make drawing them with the model easier later.

Edit: I was bored ...

class Planete
{
public:
    Planete (const std::string& nom, double masse, double diametre, double x, double y, double z)
        : m_nom(nom), m_masse(masse), m_position(x, y, z) {}
    virtual ~Planete() {}

    // default implementation as most planets don't have people
    virtual unsigned long HumanPopulation() { return 0; } // virtual with default implemenation, each planet can change it
    virtual double Temp() = 0; // pure virtual each planet must have it's own version
protected:
    std::string m_nom;
    double m_masse;
    double m_diametre;
    class Position
    {
    public:
        Position(double x, double y, double z)
            : x_(x), y_(y), z_(z) {}
    private:
        double x_, y_, z_;
    };
    Position m_position;
};

class Terre : public Planete // Earth is a Planet
{
public:
    Terre(double masse, double diametre, double x, double y, double z)
        : Planete("Terre", masse, diametre, x, y, z) {}
    ~Terre() {}

    // override base class default virtual
    unsigned long HumanPopulation() { return CalculatePeople(); }
    double Temp() { /* yata yata */ }

private:
    unsigned long CalculatePeople() { /* figure out how many people on earth */ }
};

class Mercure : public Planete // Mecury is also a Planet
{
public:
    Mercure(double masse, double diametre, double x, double y, double z)
        : Planete("Mercure", masse, diametre, x, y, z) {}
    ~Mercure() {}

    double Temp() { /* tres chaud */ } 
};


Do you mean something like that?

Modelisation::Modelisation (int argc, char **argv, char nomFenetre [] ,
int hauteur,    int    largeur, int x, int y, Planet * planet)
{

};


Simulation::Simulation (int argc, char **argv)
{
   Obj = new Planete ("Terre", (5.98*pow(10.0,24.0)), 6378.137, 0, 0, 0);
   Model = new Modelisation (argc, argv,"Modelisation",1600 ,1004, 306, 0, Obj);
};


I'm not sure exactly what you're asking, but this works just fine:

Simulation::Simulation (Planete* planete, Model* model)
{
    Obj = planete;
    Model = model;
};

A few other notes:

  • Obj and Model should really be member variables in Simulation, rather than global variables in your Simulation.cpp.
  • I consider it a major code smell to pass argc, argv as arguments to a constructor. Rather, your main method should parse the command-line parameters, and then pass the parsed values to the constructors.


There are a few things you need to change here. First, the Planete and Modelisation variables should be members of your simulation and not global variables. So your Simulation declaration would look like this:

class Simulation
{
public:
    Simulation(int argc, char **argv);
    virtual ~Simulation();

private:
    Planete *Obj;
    Modelisation *Model;
}

With regard to passing your Planete object to the Modelisation, you can also have the Modelisation have a Planete member like this:

class Modelisation
{        
    // stuff you already have...
private:
    Planete *planete;
}

Then you can change your Modelisation constructor to take a Planete pointer and assign it in the constructor:

Modelisation (Planete *p, int argc, char **argv, char[], int, int, int, int)
{
    // Stuff that's already there...
    planete = p;    
}

Now you have to be careful here because you have to be sure about who owns Planete and who should delete it. Deleting it twice will lead to bad things. I'd recommend using shared_ptr to keep from doing the wrong thing there.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号