Domanda

I've come across this a few times and I ended up removing the initial constructor. I have searched google but I don't even know what this is called...

class you {

    private:
        string name;
        int number; 
        COLORREF color;   
        drinks favoriteDrink;  // here

    public:
        you(string Name, int Number, COLORREF Color);
        string GetName();
        int GetNumber();
        COLORREF GetColor();

};

Drinks is another class and its constructor looks like: (int x, bool y). I was wanting to initialize it further in. Again, normally I just remove the constructor and write a function ex: init(w/e). Is there a way to do this?

È stato utile?

Soluzione

When you define a constructor, it can include a member initialiser list. That's the proper way to initialise members and base classes. So you'd implement the constructor of you like this:

you::you(string Name, int Number, COLORREF Color) :
  name(Name),
  number(Number),
  color(Color),
  drink(whatever_arguments, you_want)
{
  // body as usual
}

Note that this is the only way to initialise data members of a class. If you instead do this:

you::you(string Name, int Number, COLORREF Color)
{
  name = Name;
  number = Number;
  color = Color;
}

then you're not initialising the members, you're assigning to them. The empty member initialiser list will first default-initialise them. That means calling the default constructor for classes, and leaving an uninitialised value for primitive types. Then, the constructor body overwrites them by assigning into them.

It's always better to use member initialiser lists, because you skip the (useless) default initialisation. Sometimes, it's also the only way, if you have a non-assignable member (such as a const member, a reference, or simply an object without an accessible assignment operator).

Altri suggerimenti

Depending how you feel about using new and delete, the following could achieve what you were asking.

Angew's method is the best way if you know the values for x and y early enough, if you need to construct favoriteDrink later, you could consider something like the following:

class drinks; // Forward declare class rather than #including it    

class you 
{    
private:
    string name;
    int number; 
    COLORREF color;   
    drinks* favoriteDrink;  // Constructor will not be called

public:
    you(string Name, int Number, COLORREF Color);
    ~you();
    void someFunction(void);
    string GetName();
    int GetNumber();
    COLORREF GetColor();    
};

Then in the implementation:

#include "drinks.h" // Include it now we need it's implementation

you::you(string Name, int Number, COLORREF Color) :
  name(Name),
  number(Number),
  color(Color),
  favoriteDrink(NULL) // Important to ensure this pointer is initialised to null
{
  // body as usual
}

you::~you()
{
   delete favoriteDrink; // Ok to delete even if it was never newed, because we initialised it to NULL
   favoriteDrink = NULL; // Always set your pointer to null after delete
}

void you::someFunction(void)
{
   favoriteDrink = new drinks(3, 6) // Then once you know your values for x and y

   // Always check if the pointer is null before using
   if (favoriteDrink)
   {
      // Use the pointer
   }
}

Edit: As Angew points out there are better ways of managing pointers in C++11, if you've got the option of using a modern compiler his suggestions would result in nicer looking and safer code.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top