Help with Object Oriented Programming with C++
I ne开发者_如何学Ced some help figuring this out if it is possible. I am still very new to this so please forgive me. I have an array of an object that I want a method to manipulate for me. I'm not sure how to best put this in words so I will use an example.
#include <iostream>
using namespace std;
class fruit
{
private:
int amount;
public:
void eat();
};
void fruit::eat()
{
//manipulate the amount for apples at both indexes here
}
int main()
{
fruit apples[2];
fruit pie;
pie.eat();
return 0;
}
I want to change the amount at both indexes in the apples array using the eat() function. How would I go about doing this. I'm sorry if this seems stupid.
Well actually your question as well as many of the answers don't seem correct, because it doesn't make sense fruit eating fruit. What does it mean "fruit eating fruit"? Could you please explain?
A possible and reasonable class design should do something like this:
class person
{
public:
void eat(edible *item) {}
void drink(drinkable *item) {}
void sleep(double duration) {}
//...
};
class edible
{
public:
virtual ~edible() {}
virtual double get_calories() = 0; //pure virtual function
//...
}
class fruit : public edible
{
public:
virtual double get_sweetness() = 0; //pure virtual function
//...
}
class apple : public fruit
{
public:
//define pure virtual functions
}
class banana : public fruit
{
public:
//define pure virtual functions
}
std::vector<edible*> items;
items.push_back(new apple());
items.push_back(new apple());
items.push_back(new banana());
items.push_back(new banana());
person nawaz;
for(int i = 0 ; i < items.size() ; i++ )
nawaz.eat(items[i]);
nawaz.sleep(8 * 60 * 60); //8 hours!
I'm afraid that there are quite a few conceptual errors here.
To address your immediate question: your fruit class can't understand the "basket" it is in, so it's not reasonable to ask it to work on the basket.
When you say
fruit apples[2];
you are making two apple objects, each of which has an eat() method (I'll come back to that in a moment, because I'm not sure that makes sense) and then put them into an array. The array itself (I refered to it as a basket before) holds apples but does not have any eat() method. The apples do not have any knowledge that they are in the array. So in order to eat the apples you need some code to traverse the array (forgive this syntax, it's years since I wrote c++)
for ( int i = 0; i < 2; i ++ ){
apples[i].eat();
}
Now the question is where should that code go? And this is fundamental to the idea of OO programming, you think about what objects could reasonably "understand" this kind of operation, have responsibilities for looking after fruit. And hence you might have a Basket class, or some such.
Now onto the next object
fruit pie;
pie.eat();
Some problems here, first of all a pie is surely not a fruit. Consider all the things a fruit can do, and all the things a pie can do, they are very different - OK, you can slice them both, and eat them both, but they are no more similar than any other food. When you create classes you look for key similarities: Apples, Oranges, yep they have useful similarities perhaps, so Fruit as a class makes sense.
Second problem, I think you're expecting pie.eat() to have some effect on the array of apples. But these are completely distinct object. Two objects of the same class do not usually know ablout each other (there's some advanced techniques for making that possible, but don't even think about this now).
Now onto the final and I think most crucial point: the eat() method. In my world apples don't eat things, nor do they eat themselves. When doing OO, to a large extent you are modelling the real world. When you get something like this, a method that doesn't really correspond to the objects in question it probably implies that there is another class of objects we haven't identified yet.
It's not clear what kind of actions you are modelling. If you are tracking your inventory of fruit then you might have a Basket class. With methods such as
addFruit( arrayOfFruit);
takeFruit( what kind of fruit I want);
howManyFruit(kind of fruit);
If you are modelling calorie consumption you might have methods on Fruit
calories = takeOneBite();
biteLeft = howManyBitesLeft();
So we need to understand what you really want to do with the fruit before we can help further.
First of all, no need to ask for forgiveness, websites like stackoverflow exist so questions get answered. If anyone ever has a "smart-ass" attitude towards you, it's their problem, not yours.
Now, to your question: In your eat() method you have a comment stating that you want to manipulate the amount for apples. But that method belongs to the whole fruit class so what you really want is to manipulate the amount for any given fruit, right? Also, it's not very clear what exactly you want to manipulate so if you could provide a better explanation I guess you will get a lot more answers.
I will be waiting! :)
You need to pass the apples
array to eat
function. Something like this:
void fruit::eat(fruit* apples, unsigned int count)
{
for(unsigned int apple = 0; apple < count; ++apple)
{
apples[apple].amount = 0;
}
}
and in main()
{
pie.eat(apples,2)
}
You can't, not from within the class method (function). A method always works for one instance, like your fruit pie
. The arrays of apples are two instances, so you just call eat()
on each of them:
fruit apples[2];
apples[0].eat();
apples[1].eat();
Since the pie
object needs to modify apples
, one of way of implementing is to overload fruit::eat()
to take an argument of type fruit*
.
#include <iostream>
using namespace std;
class fruit
{
private:
int amount;
public:
void eat(fruit *obj);
void eat(){};
};
void fruit::eat(fruit *obj)
{
obj[0].amount = 10; // Modify here to what ever value you need
obj[1].amount = 20;
}
int main()
{
fruit apples[2];
fruit pie;
pie.eat(apples);
return 0;
}
Results: ideone . Also note that this is doing what you had asked in question but the design is bad though.
精彩评论