【问题标题】:C++ overloading and picking right functionC++ 重载和选择正确的函数
【发布时间】:2012-10-26 08:15:35
【问题描述】:

C++方法重载问题

我有 1 个父类调用 Vehicle

我有 2 个子类叫 Motorcycle 和 Car

我有这个值调用 getNoOfWheels();

父类得到了那个方法,摩托车和汽车也得到了。

假设我提示用户输入

string vehicleType;
cout << "What is your vehicle type" << endl;
cin >> vehicleType;

根据用户输入,我如何让程序根据 vehicleType 选择正确的函数,我知道如果 VehicleType== 可以使用,但这违背了重载的目的。

之前有人建议使用虚拟方法。这种情况下

virtual int noOfVerticles() const { return 0; }

对于 shape.h

我对汽车和摩托车有相同的功能,但是我如何让 noOfVerticles 从基于车辆类型的子类中选择正确的功能

我试过这样的东西..

Vehicle cVehicle;
Car &rCar = &cVehicle;


if(inVehicle=="Car")
{
cout << rCar.noOfWheels() << endl;
}

我得到一个错误说..

invalid initizliation of non-const refenrece of type "Car&" from an rvaleu of type Vehicle*

和...

这是我在 Car.cpp 的虚拟功能

public:
virtual int noOfWheels() const { return 4; }

谢谢!

【问题讨论】:

  • 这看起来像是一道作业题。在这种情况下,请添加标签作业。另外,请先向我们展示您的尝试,然后提出具体问题。
  • @sahaj 作业标签是obsolete
  • 我建议阅读有关多态性的内容。这个怎么样:cs.bu.edu/teaching/cpp/polymorphism/intro
  • @user1600289 如果你有一个指向车辆的指针并且你有代码pVehicle-&gt;noOfWheels(),那么正确的虚函数将被自动选择,这就是虚函数的工作原理。如果这对您不起作用,那么您做错了,我们需要查看您的所有代码。

标签: c++


【解决方案1】:

当你这样做时

Car &rCar = &cVehicle;

然后你声明rCar 是一个引用,但是你给它分配了一个指针。 & 符号 (&amp;) 会根据使用的位置执行不同的操作。

当它用于&amp;cVehicle 时,它是地址 运算符,并返回一个指向cVehicle 的指针。在变量声明中使用时,它会告诉编译器该变量是一个引用。


至于您的问题,您的做法似乎有些错误。使用虚方法时,您不必检查对象的类型,编译器会为您处理。

假设你有这个声明:

Vehicle *pVehicle = new Car;

现在变量pVehicle 是一个指向基类的指针,但是由于它被分配了一个指向子类的指针,所以虚函数无论如何都可以工作:

std::cout << "Number of wheels = " << pVehicle->noOfWheels() << '\n';

上面会打印出轮子的数量是 4,因为编译器会自动调用正确的函数。如果您稍后将pVehicle 更改为指向Motorcycle 实例,并再次执行上述打印输出,它会正确显示2。

【讨论】:

    【解决方案2】:

    虚拟方法的全部意义在于让您能够通过统一的方法调用来调用特定于类型的方法。

    这在内存中是这样表示的(这不是实际的内存布局,只是为了更好的想象):

    [some class attribute]
    [another class attribute]
    [pointer to getNoOfWheels()]
    [more class attributes]
    

    当您在程序中调用noOfVerticles() 时,它会调用[pointer to getNoOfWheels()] 指向的任何内容(这与“正常调用”相反,即调用Vehicle::getNoOfWheels())。

    当您创建Vehicle 的实例时:

    [pointer to noOfVerticles] = Vehicle::getNoOfWheels()
    

    如果您创建CarBike,它将被表示:

    [pointer to noOfVerticles] = Car::getNoOfWheels()
    [pointer to noOfVerticles] = Bike::getNoOfWheels()
    

    假设您有以下类层次结构:

    class Vehicle {
    public:
        virtual int getNoOfWheels() const { return 0; } // Though this should be pure virtual method
    }
    
    class Car : public Vehicle {
    public:
        virtual int getNoOfWheels() const { return 4; }
    }
    
    class Bike : public Vehicle {
    public:
        virtual int getNoOfWheels() const { return 2; }
    }
    

    这会突然发生:

    Vehicle *one = new Vehicle(),
            *two = new Car(),
            *three = new Bike();
    
    one->getNoOfWheels(); // Vehicle::getNoOfWheels() - thus 0
    two->getNoOfWheels(); // Car::getNoOfWheels() - thus 4
    three->getNoOfWheels(); // Bike::getNoOfWheels() - thus 2
    
    // And you still call original method of a vehicle in car:
    two.Vehicle::getNoOfWheels(); // 0
    

    您现在唯一要做的就是为汽车分配正确的新实例,但这已在ForEverS's answer 中介绍。

    【讨论】:

      【解决方案3】:

      尝试使用..

      Vehicle *vehicle1= new Car(); 
      
      Vehicle *vehicle2= new MotorBike();
      

      您可以调用函数vehicle1-&gt;getNoOfWheels()vehicle2-&gt;getNoOfWheels()。 这将调用 Car 和 MotorBike 类的函数。仅当您在基类车辆中声明您作为虚拟功能时才会发生这种情况。

      同样适用于引用变量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-14
        • 2015-05-19
        • 1970-01-01
        • 1970-01-01
        • 2013-02-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多