использование родительской функции (наследование c ++) - PullRequest
1 голос
/ 02 октября 2011

У меня есть четыре файла .cpp, Animal, Cattle, Sheep, DrugAdmin.Animal является родительским классом Cattle, и имеет calcDose(), который вычисляет количество дозы.DrugAdmin является основной функцией.Дело в том, что я хочу использовать функцию calcDose() по-другому (крупный рогатый скот, овцы), и для класса Animal функция calcDose() не требуется.Однако каждый раз, когда я пытаюсь использовать calcDose(), он автоматически вызывает функцию в классе Animal, даже если я хочу использовать класс Cattle.Это код, который я сделал до сих пор.(Я сократил это)

Animal.cpp

#include "Animal.h"
#include <string>
using namespace std;

Animal::Animal(int newid, double newweight, int yy, int mm, int dd, char newsex, vector<Treatment> treatArray)
{
    id = newid;
    weight = newweight;
    yy = yy;
    mm = mm;
    dd = dd;
    accDose = 0;
    sex = newsex;
}
double Animal::calcDose(){
    return 0;
}

Cattle.cpp

#include "Cattle.h"
using namespace std;


Cattle::Cattle(int newid, double newweight, int yy, int mm, int dd, 
           char newsex, vector<Treatment> newtreatArray, string newcategory)
    : Animal(newid, newweight, yy,mm,dd, newsex, newtreatArray)
{
    id = newid;
    weight = newweight;
    accDose = 0;
    sex = newsex;
    Cattle::category = newcategory;
}

Cattle::~Cattle(){}

double Cattle::calcDose(){
    if(getDaysDifference() < 90 || getCategory() == "Meat"){
        accDose = 0;
        return accDose;
    }
    else if(getCategory() == "Dairy"){
        if (weight < 250 || accDose > 200){
            accDose = 0;
        }
        else{
            accDose = weight * 0.013 + 46;
        }
        return accDose;
    }
    else if(getCategory() == "Breeding"){
        if (weight < 250 || accDose > 250){
            accDose = 0;
        }
        else{
            accDose = weight * 0.021 + 81;
        }
        return accDose;
    }
    else
    {
        //cout << "It is not valid category" << endl;
    }
}

Класс овец почти такой же, но содержание calcDose()

DrugAdmin.cpp

#include "DrugAdmin.h"
using namespace std;

vector<Animal*> vec_Animal;

void addAnimal(){
    int select=0;
    int id;
    double weight;
    int yy;
    int mm;
    int dd;
    char sex;
    string category;
    vector<Treatment> treatArray;

        //user inputs all the values (i've cut it down)

     Animal* c1 = new Cattle(id,weight,yy,mm,dd,sex,treatArray,category);

        vec_Animal.push_back(c1);
}

void administerDose(int id)  //Main Problem
{


   vector<Animal*>::iterator ite_Animal = vec_Animal.begin();
    for(ite_Animal; ite_Animal != vec_Animal.end(); ++ite_Animal)
        cout<<"\nVector contains:"<< (*ite_Animal)->calcDose();
}

Извините за длинный и запутанный вопрос.Последний вопрос: у Cattle есть дополнительный элемент данных, равный category, но система также не распознает это.Он распознает, как будто это Animal объект.Могу ли я дать совет, пожалуйста?

Приветствия

Ответы [ 3 ]

5 голосов
/ 02 октября 2011

каждый раз, когда я пытаюсь использовать calcDose(), он автоматически вызывает функцию в Animal классе

Звучит так, будто вы забыли сделать calcDose a virtualфункция-член .

Последний вопрос: Cattle имеет дополнительный элемент данных, который является категорией, но система также не распознает это.Он распознает, как будто это Animal объект.

Я не уверен, что вы подразумеваете под "системой", "распознающей" что-либо, но если вы обращаетесь к объекту Cattle через Animal*, то вы не можете попасть к Cattle -специализированным членам.Вы должны будете использовать либо Cattle*, либо, опять же, полиморфизм / virtual.

2 голосов
/ 02 октября 2011

В отличие от Java (и многих других языков), C ++ по умолчанию использует так называемое «статическое связывание». Статическое связывание означает, что вызываемая функция основана на объявленном типе объекта (или указателя) во время компиляции, а не на том, чем фактически является объект (или на что фактически указывает указатель).

Альтернативой статическому связыванию является «динамическое связывание». В динамическом связывании вызываемая функция основана на том, чем на самом деле является объект (или на что фактически указывает указатель) во время выполнения.

Чтобы включить динамическое связывание, что вам нужно, если вы настроили иерархию наследования и поддерживает указатели базового класса (Animal * s), вам нужно использовать ключевое слово virtual. virtual делает функцию динамически связанной, так что вызовы этой функции будут отражать фактический тип времени выполнения объекта (Cattle), а не объявленный во время компиляции тип указателя (Animal *).

Чтобы объявить функцию виртуальной, вы должны поставить ключевое слово virtual перед возвращаемым значением в объявлении функции (в файле описания класса / .h):

class Animal
{
    virtual void calcDose();
    // ...
};

Это также хороший способ поместить виртуальный объект в переопределенную функцию в производном классе (calcDose () в Cattle), хотя виртуальный тип подразумевается для унаследованных функций, поэтому указывать его здесь не обязательно.

И последнее, что нужно для обеспечения динамического связывания, - это наличие у вас указателей (или ссылок) на объекты, а не на объекты в стеке (когда вы хотите динамическое связывание). Объект в стеке (т.е. Animal a) может быть только объявленным типом, он не может указывать на производный тип класса. Таким образом, vector<Animal*>, который у вас есть, идеален, потому что эти указатели могут указывать на объекты крупного рогатого скота (или объекты животных), в то время как вектор может содержать только реальные объекты животных.

0 голосов
/ 02 октября 2011

Вы должны сделать вашу функцию calcDose виртуальной и переопределить ее в каждом подклассе: Крупный рогатый скот и т. Д. Кроме того, чтобы распознать свое животное в качестве крупного рогатого скота, вы должны привести его к классу крупного рогатого скота. Но вы должны использовать общий интерфейс базового типа большую часть времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...