0

Take a look at the initialization list of the derived class in the code below.

class city {
    private:
        int id;
        int x;
        int y;
    public:
        int getID(){return id;};
        int getX(){return x;};
        int getY(){return y;};
        city(){
            id =0; x=0; y=0;
        }
        city(int idx, int xx, int yx){
            id = idx;
            x = xx;
            y = yx;
        }
        city(city* cityobj){
            id = cityobj->id;
            x = cityobj->x;
            y = cityobj->y;
        }
};

class city_detail : public city{    
    private:
        city* neighbor;
    public:
        city_detail (city& neighborX, city& cityobj): city(cityobj){ // What???
                                                     /* ^ city(cityobj) and city(&cityobj) both work here */        
            neighbor = &neighborX;
        }
        city* getN(){return neighbor;}
    };

int main(int argc, char*argv[]){

city LA(42, 1, 2);

city PDX(7, 3, 4);

city_detail LA_Detail(PDX, LA);

cout << "LA_Detail.ID: " << LA_Detail.getID() << endl; // works both ways 
cout << "LA_Detail.x: " << LA_Detail.getX() << endl; // works both ways
cout << "LA_Detail.y: " << LA_Detail.getY() << endl; // works both ways

cout << "LA_Detail.NN: " << LA_Detail.getN() << endl; // returns address as it should

city * LA_neighbor = LA_Detail.getN(); 

cout << "LA_neighbor.ID: " << LA_neighbor->getID() << endl; // address is indeed valid
cout << "LA_neighbor.x: " << LA_neighbor->getX() << endl; // address is indeed valid
cout << "LA_neighbor.y: " << LA_neighbor->getY() << endl; // address is indeed valid


return 0;

}

Why is it that both ...: city(&cityobj) AND ...: city(cityobj) work here?

I would think that I cannot do the latter, ...: city(cityobj), and that I must pass in an address to cityobj since the base class' constructor takes in a pointer.

Why am I not getting some compile error such as:

cannot convert type city to city * ?

Clearly, I am not able to do this in other places, such as:

void getID(city* aCity){
        cout << "aCityID: " << aCity->getID() << endl;
        cout << "aCityX: " << aCity->getX() << endl;
}

void wrapper(city &aCity){
        getID(&aCity); // I must pass in the address here, else I get an error
}

city Greenway;
wrapper(Greenway); 
LazerSharks
  • 3,089
  • 4
  • 42
  • 67
  • 2
    Because of the compiler-generated copy constructor with the signature `city(city const&)`. – Cameron Nov 24 '14 at 17:30
  • Does the compiler generate for all classes a default constructor with signature `class(class const&)`? Any docs you can point to for this? – LazerSharks Nov 24 '14 at 17:33
  • 1
    Yes, unless you define your own or `= delete` it or define a move constructor (except with non-conforming MSVC). See http://stackoverflow.com/q/4943958/21475. – Cameron Nov 24 '14 at 17:36
  • Ah, so I did not even need to write my own sort of copy-like constructor `city(city* cityobj)`. Thank you. Do you know what to call that type of constructor I wrote? Or is it not standard practice and does not have a name? – LazerSharks Nov 24 '14 at 17:42
  • 1
    Well, it's just a plain (user-defined) constructor. In this case it would be standard practice just to use the generated copy constructor, but often you need to define a custom one (e.g. if your object allocates memory in its constructor). In that case, though, it's still not a great idea to define one that takes a pointer instead of the usual `const&`, because the entire language and standard library is based around copying objects using the standard signature. – Cameron Nov 24 '14 at 17:46
  • Read about [Special Member Functions](https://en.wikipedia.org/wiki/Special_member_functions) – Chris Drew Nov 24 '14 at 18:21

1 Answers1

2

The reason it works is that when you call city(cityobj) it uses the compiler's implicitly defined copy constructor, and when you call city(&cityobj) it uses the converting constructor you defined yourself: city(city* cityobj).

You didn't mean to say neighbor(&cityobj) did you?

Mark B
  • 95,107
  • 10
  • 109
  • 188