Constructor

Started by
16 comments, last by Perost 15 years, 4 months ago
Hello. I was donig a constructor whose code follows: Jogador() { *hp=new int; *mp=new int; *max_hp=new int; *max_mp=new int; *forca=new int; } If I make a object and try to pass arguments (ex.:Jogador Daniel(23,45,12,23,78)) the compiler returns a error :" too many initializers".So I tried to do this: Jogador() { *hp=new int(23); *mp=new int(45); *max_hp=new int(12); *max_mp=new int(23); *forca=new int(78); } But I want to do several objects and don´t want all of them starting with the same parameters (because the code is a simple game in text mode).I'm confused.Is There a way to to do each object start with different parameters?? Thanks
Advertisement
Do you have a constructor that takes five arguments? Also, do you really have pointers to pointers as members and why on earth are you allocating something as simple as a single int dynamically?
Just to try to LEARN dinamic allocation.
That's one of the three questions answered. Post the full class definition... there's quite a few weird things about that code, and it's difficult to tell what needs to be fixed and what doesn't.
Quote:Original post by Asafe
But I want to do several objects and don´t want all of them starting with the same parameters (because the code is a simple game in text mode).I'm confused.Is There a way to to do each object start with different parameters??
Thanks


Like any normal functions, a constructor can take parameters. You have to say what the parameters should be:

Jogador(int a, int b, int c, int d, int e) { /* ... */


and then you can use those within the function. For constructors, you can also use the initialization list, which is more direct:

Jogador(int hp, int mp, int max_hp, int max_mp, int forca): hp(hp), mp(mp), max_hp(max_hp), max_mp(max_mp), forca(forca) {}


In any case, you then call the constructor by passing those arguments, just as you showed:

Jogador Daniel(23, 45, 12, 23, 78);


But you might want to consider the design a little more - usually you should only *create* a player who starts with full health and mp, so only pass those values and duplicate them at the beginning:

Jogador(int max_hp, int max_mp, int forca): hp(max_hp), mp(max_mp), max_hp(max_hp), max_mp(max_mp), forca(forca) {}Jogador Daniel(23, 45, 78);


In any case, this is not a good place to try to learn dynamic allocation. First, because there are other things you have to learn to make your code work :) and second because it is actually a difficult topic, and experienced programmers very rarely do it directly anyway. Learn to use tools like std::vector; and then when you are more skilled, you will find that you are... still using tools like std::vector, because they are powerful.
Thanks.It was mistake of mine don't think this (arguments in the constructor).
But the lasts sentences I didnot understood ...However thank you.
Firstly, from your code appears that the members are pointers to pointers. This doesn't make absolutely any sense here and in any case n itself is still unitialized when you dereference it in the constructor. n itself needs to be allocated too, and it should seem bizarre to you that it takes two memory allocations to store a plain integer.

class X{    int**n;public:    X(int value)    {        n = new int*;        *n = new int(value);    }};


So, you might just do with a simple pointer

class X{    int*n;public:    X(int value)    {        n = new int(value);    }};


But now you don't want to leak memory when the object goes out of scope, so you'll have to write a destructor that delete's it.

But what happens if an instance is created as a copy of the other? Both instances would point to the same int, and both would try to delete it in the destructor. Oh well, you need to write the copy constructor.

Now, what if one instance is assigned to the other. Firstly, the current pointer held in an object would be overwritten (leaked), and then you'll have the same trouble as with copying. So you need the overloaded assignment operator too.

class X{    int*n;public:    X(int value)    {        n = new int(value);    }    ~X()    {        delete n;    }    X(const X& other)    {        n = new int(*other.n);    }    //in the following you must be careful not to destroy the object by self-assingment    //here the new value is allocated before old is destroyed    const X& operator=(const X& other)    {        int* p = new int(*other.n);        delete n;        n = p;        return *this;    }};


And this is the benign case of having just one dynamically allocated pointer. With more pointers there's also the possibility of some memory allocation failing, and therefore leaking the successfully allocated memory if any operation couldn't be completed.

There are reasons why such dynamically allocated members are only used low-level classes that are used as building blocks for higher level classes (like std::vector, smart pointers etc).

You might make Jogador robust itself - no pointer members -, and then perhaps create instances of that dynamically. At least it would be a more practical use case for dynamic allocation (e.g what would you do supposing Jogador was a polymorphic class).

Zahlman will it compile with same named members and parameters?
max_hp(max_hp) for example ?
Jogador(int max_hp, int max_mp, int forca): hp(max_hp), mp(max_mp), max_hp(max_hp), max_mp(max_mp), forca(forca) {}
Quote:Original post by Black Knight
Zahlman will it compile with same named members and parameters?
max_hp(max_hp) for example ?
Jogador(int max_hp, int max_mp, int forca): hp(max_hp), mp(max_mp), max_hp(max_hp), max_mp(max_mp), forca(forca) {}
Yes. That's valid for the intializer list, since the compiler knows that you're initializing a member variable with a constructor parameter.
Quote:Original post by Black Knight
Zahlman will it compile with same named members and parameters?
max_hp(max_hp) for example ?
Jogador(int max_hp, int max_mp, int forca): hp(max_hp), mp(max_mp), max_hp(max_hp), max_mp(max_mp), forca(forca) {}

Yes, it will. When refering to the member being initialized in the initializer list, only members can be initialized so there is no ambiguity what is being refered to. When passing parameters to the corresponding member constructor, the normal name lookup is employed where parameters take priority over members.

This topic is closed to new replies.

Advertisement