简体   繁体   中英

C++ Passing a set of objects to a member functions of abstract class

I would like to pass objects to a member functions of class and execute some functions from within it. When I do this using the *myCars pointers, everything works fine. But when I try to pass this to do the same for a pure virtual class, the program returns error (see Solution A). I've got a temporary solution (see Solution B), but it does not seem right to me. Any idea to fix it?

main.cpp

#include <iostream>
#include "car.h"
#include "veicles.h"
#include "traffic.h"

int main(){

        int number = 3;
        Car *myCars = new Car[number];

        Traffic mtc;
        mtc.import(myCars, number);

        Veicles *myVeicles = new Car[number];

//      Solution A
//      Traffic mtvA;
//      mtvA.import(myVeicles, number);

//      Solution B
        std::cout << "\nsolution B\n";
        Traffic mtvB;
        mtvB.import(&myVeicles, number);

        delete[] myCars;
        delete[] myVeicles;

        return 0;
}

car.h

#ifndef CAR_H
#define CAR_H

#include <iostream>
#include "veicles.h"

class Car : public Veicles{
public:
    void move();

};

#endif

car.cpp

#include "car.h"

void Car::move(){

        std::cout << "the car is moving\n";
}

traffic.h

#ifndef TRAFFIC_H
#define TRAFFIC_H

#include "car.h"

class Traffic{
public:

    void import(Car p[], int number);
    void import(Veicles *v[], int number);
private:

    Veicles *vc;

};

#endif

traffic.cpp

#include "traffic.h"
#include "car.h"

void Traffic::import(Car p[], int number){

        for(int i = 0; i < number; i++){
                p[i].move();
        }
} 

void Traffic::import(Veicles *v[], int number){

        vc = *v; 
        for(int i = 0; i < number; i++){
               // vc -> move();
               vc[i].move(); //  EDIT: R Sahu sugestion
        }
}

veicles.h

#ifndef VEICLES_H
#define VEICLES_H

class Veicles{
public:

    virtual void move() = 0;
};

#endif

veicles.cpp

#include "veicles.h"

// some stuffs to do latter..

makefile

all:    clean car veicles traffic main
        g++ car.o traffic.o main.o -o main.out
run:
        ./main.out

car:    car.h
        g++ -c car.cpp -o car.o

veicles: car.h veicles.h
        g++ -c veicles.cpp -o veicles.o

traffic: traffic.h car.h
        g++ -c traffic.cpp -o traffic.o


main: traffic.h car.h
        g++ -c main.cpp -o main.o

clean:
        rm -f *.o
        rm -f *.gch
  void import(Car p[], int number);

is the same as

  void import(Car* p, int number);

You may not call it with an argument of type Vehicle* since a base class pointer cannot be automatically converted to derived class pointer.

Imagine you had:

class Truck : public Veicles{
 ...
};

and

Veicles *myVeicles = new Truck[number];

If the compiler let you call that function, you would suddenly able to use a Truck where a Car was expected. That would lead to disaster.


The following function works

void Traffic::import(Veicles *v[], int number){
   vc = *v; 
   for(int i = 0; i < number; i++){
      vc -> move();
   }
}

However, please note that you are not using i to access the elements of vc . You are calling move() on the first object only.

The following would be a problem.

void Traffic::import(Veicles *v[], int number){
   vc = *v; 
   for(int i = 0; i < number; i++){
      vc[i].move();
   }
}

The reason for that is you may not treat an array of derived class objects as an array of base class objects.

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