简体   繁体   中英

Creating instance in an another class of an object

I need to create an instance in class Crop of Plant class and i cant manage to find a way to make that work. Hope you guys can help at that.

This my main where i'm sending an object to the class crop.

int main(){

char select = 'a';
int plant_num = 2;
int crop_num = 0;

Crop crop[10];
Plant plant[20];

plant[0] = Plant("Carrots",'c');    
plant[1] = Plant("Lettuce",'l');
plant[2] = Plant("Rosemary",'r');

crop[0] = Crop(plant[0],4,2);
crop_num++;

cout << "Garden Designer" << endl;
cout << "===============";

}

class crop is where i want the instance of plant class

class Crop {

private:
    int g_length;
    int w_width;
    Plant PlantType;

public:
    Crop();
    Crop(const Plant&, int, int);

};  

class plant of which i want the instance of in class crop

class Plant {

private:
    char plant[20];
    char p_symbol;

public: 
    Plant();
    Plant(const char* n, char s);
};

Crop.cpp

#include <iostream>
#include <iomanip>
#include <cstring>
#include <new>
#include "crop.h"
using namespace std;


Crop::Crop(){



}

 Crop::Crop(const Plant& temp, int l, int w){



}

sorry if im missing something. really confused if you need Plant.cpp file content just ask me. I didn't think that file would be needed.

There is something called a Member initializer list and its place is in the constructors definition after its parameters list, preceded by a semicolon, followed by a body of a constructor. So to initialize members you can write

Crop::Crop(const Plant& temp, int l, int w) : 
  g_length(l), 
  w_width(w), 
  PlantType(temp) 
{ }

What this does is call the appropriate constructors of the members. They don't have to be copy constructors. You can explicitly call default one or any else, although it probably does not make much sense in your case.

It is because the members are instantiated before executing the body of the constructor. You would not have problem with int s, as they can be set inside the body. References, however, need to be valid at all the times, so nothing inside the body will have a "null-reference".

You could do:

Crop::Crop(const Plant& temp, int l, int w) : PlantType(temp) 
{ 
   g_length = l;
   w_width = w;
}

But any member not initialized explicitly gets initialized with a default constructor, so at //here g_lenght exists and has a value (either 0 or trash i don't recall if default is zero, i think it's thrash), and then in the body operator= gets called. While the 1st case, object is created via copy constructor.

Often this is not a big difference, however for more complicated types it might be important. Especially if constructing an empty object takes long time, and then assignment is also complicated. It's simply to better set-up object once, than create it and reset with operator= .

I personally like the look of 2nd for some reason, but it is considered a worse practice, because logically those members are meant to be constructed using some value from the start.

You're on the right track here:

crop[0] = Crop(plant[0],4,2);

This calls the constructor of the class Crop with the correct parameters. This constructor is supposed to initialize the corresponding data members with these values, but the constructor that actually takes these parameters does nothing:

Crop::Crop(const Plant& temp, int l, int w) {
    // ...
}

Use the member initializer list to initialize your data members:

Crop::Crop(const Plant& temp, int l, int w)
    : g_length(l), g_width(w), PlantType(temp)
{ }

The constructor body isn't needed until we need to do something after we've initialized our data members.

Your Crop constructor receives the Plant (and two integers) and completely ignores them. Try:

Crop::Crop(const Plant& temp, int l, int w) :
    g_length(l), w_width(w), PlantType(temp) {}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM