basic C++ question - c++

I see in a class notices of a friend this:
void show_results(Book& foreign_books) {
int total_books
total_books = foreign_books.getBooksNumber();
cout << total_books << endl;
}
this is a good class definition?
class Book{
public:
Book();
int getBooksNumber();
};
ps: i've writing this from mobile phone, and i cannot check too much documentation(I'm newbie too). I need your confirmation. ty

It's really hard to tell what you are asking. Let me offer some criticisms, though. Maybe these will help.
The show_results method should be const-correct. That means you should pass foreign_books as a const:
const Book& foreign_books
This way, your compiler will complain if you try to modify foreign_books at all in your method.
As mgb points out, your Books class won't work because the show_results method requires a Book, not a Books. But once you fix that, you probably want to make the getBooksNumber const-correct as well:
int getBooksNumber() const;
You haven't told us what you are trying to accomplish here, so it's really hard to tell if you are close to correct in what you are doing.
Finally, you missed a semicolon in your show_results method:
void show_results(Book& foreign_books) {
int total_books; // **here**
total_books = foreign_books.getBooksNumber();
cout << total_books << endl;
}

Except that Books and Book isn't the same (typ0)
And you have to have some data member in Books to store the number, and some way of generating it.
You probably also need some sort of factory to create a unique number for each Books()

I am not sure if you are trying to associate a unique number to each book or just if you are keeping track of total number of Book objects constructed so far. If former is the case then you should declare a member variable saying bookNumber in Book class, and in getBooksNumber() you should return the value assigned to the bookNumber variable. Better if you make getBooksNumber() as constant function and if you invoke this function with constant object.
If later is the case where you are keeping track of total number of Book object constructed so far, then you should have a static data member to keep track of it and you can make getBooksNumber() static as well, and can invoke getBooksNumber() without the object of call.

Related

text adventure - how to add items to 'inventory' struct/class without defining each in advance?

So far this is the most awkward thing I've come about. I have it set for integers to mark how many potions, keys, a player has, but I'm not sure exactly how I can get random items, like rocks, CPU (in the case of Dunnet), stick, shovel, etc.
I don't want to have to figure out every item in the game and assign it a variable. There has to be an easier way. I thought of using two arrays, one a string and one an int, to do the job - but this wont work for a variety of reasons one being I can't do string stringname[10], I see problems associating the two, and... the list goes on, I'm sure it just wont work that way.
Everything else is a class btw, I don't like using structs (but this is going to be used throughout the code, and accessed everywhere), so far my code is:
struct Inventory{
int Keys;
int Potions;
int getinventory() const { return Keys, Potions; }
void addkey(int amt){ Keys += amt; }
void addpotion(int amt){ Potions += amt; }
void usepotion(){Potions -= 1;}
void usekey()
{
if (Keys >> 0)
{
Keys -= 1;
}
else if (Keys << 1)
{
cout << "You do not have a key!" << endl;
}
}
};
I'm definitely still working on the getinventory(), because well, I'm not sure what I'm doing with this code, or even if I'm using it. is the only way I'm going to get this to work, to define EACH variable as I create it in the game and add it in?
I was going to handle weapons and monsters this way... but it just sucks not having a dynamic system for an inventory. I'd like to focus on parsing user input and not have to go back into the header where my main classes are consistently... plus I haven't even fully written the story yet, so I don't know whats happening...
The way this is addressed in LPMuds (and similar) is to create a generic object template. The generic template would have things like a short description, long description, define weight, value, etc.
Specific object types then inherit this class. For example, a potion is an object with all of those attributes but it also has additional actions (functions) that can be taken and possibly different attributes... Taste and color, for example.
Weapons can inherit from that general class, defining things like damage and hit percentage as a generalized notion. A sword can then inherit this weapon (that inherits the generic object) and can be further refined.
In this way, you simply need your inventory to be able to handle a generic object. The objects themselves may define additional attributes and actions. This also means that you don't need to predefine every single object as its own unique variable.
What about creating a structure like this:
struct InventoryItem
{
enum { Key, Potion, Rock, Stick, Shovel } type_;
unsigned int num_;
}
and then have Inventory contain something like a std::vector of InventoryItem.

c++ Using subclasses

I have this variable; Furniture **furnitures;
Which is an abstract baseclass to 2 subclasses, Bookcase and Couch. I add these randomly;
furnitures[n++] = new Bookcase ();
furnitures[n++] = new Couch();
.
.
For the sake of explaination. Lets set some minor variables.
Furniture private: name, prize
Bookcase private: size
Couch private: seats
How would I go about if I wanted to print out information such as; name and seats?
There are various of problems in this issue. 1, distinguish which subclass is which when I use Furniture[i]. 2, I dont want to blend too much unneccessary functions between the two subclasses that arent needed.
class Furniture
{
virtual void output() = 0;
};
class Couch : public Furniture
{
void output() override;
};
class Bookshelf : public Furniture
{
void output() override;
};
You could define the function in Furniture to save from duplicate code in subclasses like this:
void Furniture::output()
{
// We assume here the output is to cout, but you could also pass the necessary
// stream in as argument to output() for example.
cout << name << price;
}
void Couch::output()
{
Furniture::output();
cout << seats;
}
void Bookshelf::output()
{
Furniture::output();
cout << size;
}
You should never use arrays polymorhphically. Read the first item (I think it's the first) in Scott Meyers' More Effective C++ book to find out why!
In fact, you should almost never use raw arrays in C++ anyway. A correct solution is to use a std::vector<Furniture*>.
How would I go about if I wanted to print out information such as;
name and seats?
There are various of problems in this issue. 1, distinguish which
subclass is which when I use Furniture[i]. 2, I dont want to blend too
much unneccessary functions between the two subclasses that arent
needed..
You are facing this problem because you are abusing object-oriented programming. It's simple: object-oriented programming makes sense when different types implement an abstract common operation and the concrete type is chosen at run-time. In your case, there is no common operation. Printing (or receiving) the number seats is for one type, printing (or receiving) a size is for the other type.
That's not to say that it's bad or wrong, but it's simply not object-oriented.
Now C++ would not be C++ if it didn't offer you a dangerous tool to get out of every dead end you've coded yourself into. In this case, you can use Run-Time Type Identifcation (RTTI) to find out the concrete type of an object. Google for typeid and dynamic_cast and you'll quickly find the solution. But remember, using RTTI for this problem is a workaround. Review your class design, and change it if necessary.

Sort function which takes a vector of pointers to an interface class

I've recently begun learning c++ (no prior programming knowledge). I've used the book "Jumping into c++" By Alex Allain and i've found it most useful! However i've reached the chapters of classes, inheritence and polymorphism, and while i do understand most of it I just cannot wrap my head around this one problem.
In the book I am asked to solve the following problem:
Implement a sort function that takes a vector of pointers to an interface class, Comparable,
that defines a method, compare(Comparable& other), and returns 0 if the objects are the
same, 1 if the object is greater than other, and -1 if the object is less than other. Create a class
that implements this interface, create several instances, and sort them. If you're looking for
some inspiration for what to create—try a HighScoreElement class that has a name and a
score, and sorts so that the top scores are first, but if two scores are the same, they are sorted
next by name.
I've created the classes Comparable and HighScores:
class Comparable {
public:
virtual int compare(Comparable& other)=0;
};
class HighScore : public Comparable {
public:
HighScore(int, std::string);
virtual int compare(Comparable& other);
private:
int highscore;
std::string name;
};
If i try to overwrite the inherited function in HighScore, i am not able to compare, for instance the int highscore, with the int highscore of (Comparable& other), since i cannot access the other.highscore. Example below:
int HighScore::compare(Comparable& other){
if (highscore == other.highscore) {
return 0;
}
//...
}
I thought i could maybe change the virtual method to something like:
int HighScore::compare(HighScore& other){
if (highscore == other.highscore) {
return 0;
}
//...
}
Since that would allow me to access other.highscore (and i had hoped that i would work since HighScore also can be considered a Comparable. But alas no such luck. What should I do, i litterally have no clue on how to continue and i would appreciate any help i can get. Thanks :)
Indeed, trying to choose behaviour based on the run-time type of two or more objects is a bit fiddly in a single-dispatch language like C++.
The simplest solution is to use RTTI to determine whether the other object has a type comparable with ours:
int HighScore::compare(Comparable& other){
int other_highscore = dynamic_cast<HighScore&>(other).highscore;
if (highscore == other_highscore) {
return 0;
}
//...
}
This will throw an exception if the types aren't comparable, which is probably the best you can do.
Alternatively, you could implement a double-dispatch mechanism (such as the "Visitor Pattern"), involving two virtual functions. I'll let you research it yourself, since an example would be long-winded and not particularly inspiring.
Hopefully, you will soon learn how to do this using compile-time generics rather than run-time abstract interfaces, which is much more idiomatic in C++. If the book doesn't teach you that, throw it away and get one of these instead.
You can write a pulic getter function to get the score
class Comparable {
public:
int get_score() const = 0;
//
}
class HighScore : public Comparable {
public:
int get_score() const { return highscore; }
and then use that for comparison.
int HighScore::compare(Comparable& other){
if (highscore == other.get_score()) {
^^^^^^^^^^^
return 0;
}
//...
}
But since only the derived class has highscore member you should probably change what you pass to compare.
int HighScore::compare(HighScore& other)
OR move highscore member to the base class. Whichever males sense to you.
I'd suggest picking another book on the subject. Since this exercise seemed to be vague and doesn't give good understanding on polymorphism. The tricky part is that when you get Comparable in your compare method you have no clue, if it is HighScore or some other derived class. And in case if the class you are attempting to compare is not an instance of HighScore such terms as equal less and greater doesn't have any meaning. Thus there is no way to solve this correctly. You can of course use dynamic_cast to check if it is HighScore, but still if it doesn't there is no good answer if it greater, lesser or equal to something that isn't a HighScore.
Just imagine that there is something like class Color : public Comparable { exists. What should you return in case if you get Color to be compared with HighScore? Is blue bigger than 10, or Yellow less than 15, what red is equal to?

Class and Member Function (beginner)

I'm currently reading a c++ book, and I have a few questions.
1) Is void only used to declare a return type in this example?
2) If void causes it NOT to return data to the calling function, why is it still displaying the message "Welcome to the Grade Book!"?
3) Isn't it easier to create a simple function instead of making an object?
#include <iostream>
using namespace std;
class GradeBook
{
public:
void displayMessage()
{
cout << "Welcome to the Grade Book!" << endl;
}
};
int main()
{
GradeBook myGradeBook;
myGradeBook.displayMessage();
}
That's the only use in this example. You can also have pointers to void (void *).
You're not returning that message. You're printing it. In C++, methods and functions can have side effects. One possible side effect is output.
Yes, in this case. However, this is not a realistic example of the benefits of objects. For that, see How do I describe Object-Oriented Programing to a beginner? Is there a good real-world analogy? among many places.
Is void only used to declare a return type in this example?
Yes, it indicates that displayMessage() will not return back anything to it's caller.
It can also be used as a void *, i.e: A generic pointer which can point to anything, but it is not being used in that way in your example.
If void causes it NOT to return data to the calling function, why is it still displaying the message "Welcome to the Grade Book!"?
The message is not returned to the caller of the function, the message is directed to the standard output when the control was in the function and executing that particular statement.
Isn't it easier to create a simple function instead of making an object?
It's not a matter of ease. It is more of an matter of Object Oriented design principles.
The purpose of having classes and member functions is to bind together the data and the methods that operate on that data in a single unit. You might want to pick up a good book and read up Encapsulation & Abstraction.
The Definitive C++ Book Guide and List
In your case the function "displayMeassage" is not returning the string, it is just printing your message.
Returning means, suppose an example:
class A
{
int num=0;
int getNum()
{
return num;
}
};
void main()
{
A a;
int no=a.getNum();
cout<<"no : "<<no;
}
In above example, then way getNum is returning the number that is what returning is
called.
Whatever you are taking the example is not good to understand the return concept.
Thanks

Good practice for choosing an algorithm randomly with c++

Setting:
A pseudo-random pattern has to be generated. There are several ways / or algorithms availible to create different content. All algorithms will generate a list of chars (but could be anything else)... the important part is, that all of them return the same type of values, and need the same type of input arguments.
It has to be possible to call a method GetRandomPattern(), which will use a random one of the algorithms everytime it is called.
My first aproach was to put each algorithm in it's own function and select a random one of them each time GetRandompattern() is called. But I didn't come up with another way of choosing between them, than with a switch case statement which is unhandy, ugly and inflexible.
class PatternGenerator{
public:
list<char> GetRandomPattern();
private:
list<char>GeneratePatternA(foo bar);
list<char>GeneratePatternB(foo bar);
........
list<char>GeneratePatternX(foo bar);
}
What would be a good way to select a random GeneratePattern function every time the GetRandomPattern() method is called ?
Or should the whole class be designed differently ?
Thanks a lot
Create a single class for each algorithm, each one subclassing a generator class. Put instances of those objects into a list. Pick one randomly and use it!
More generically, if you start creating several alternative methods with the same signature, something's screaming "put us into sibling classes" at you :)
Update
Can't resist arguing a bit more for an object-oriented solution after the pointer-suggestion came
Imagine at some point you want to print which method created which random thing. With objects, it's easy, just add a "name" method or something. How do you want to achieve this if all you got is a pointer? (yea, create a dictionary from pointers to strings, hm...)
Imagine you find out that you got ten methods, five of which only differ by a parameter. So you write five functions "just to keep the code clean from OOP garbage"? Or won't you rather have a function which happens to be able to store some state with it (also known as an object?)
What I'm trying to say is that this is a textbook application for some OOP design. The above points are just trying to flesh that out a bit and argue that even if it works with pointers now, it's not the future-proof solution. And you shouldn't be afraid to produce code that talks to the reader (ie your future you, in four weeks or so) telling that person what it's doing
You can make an array of function pointers. This avoids having to create a whole bunch of different classes, although you still have to assign the function pointers to the elements of the array. Any way you do this, there are going to be a lot of repetitive-looking lines. In your example, it's in the GetRandomPattern method. In mine, it's in the PatternGenerator constructor.
#define FUNCTION_COUNT 24
typedef list<char>(*generatorFunc)(foo);
class PatternGenerator{
public:
PatternGenerator() {
functions[0] = &GeneratePatternA;
functions[1] = &GeneratePatternB;
...
functions[24] = &GeneratePatternX;
}
list<char> GetRandomPattern() {
foo bar = value;
int funcToUse = rand()%FUNCTION_COUNT;
functions[funcToUse](bar);
}
private:
generatorFunc functions[FUNCTION_COUNT];
}
One way to avoid switch-like coding is using Strategy design pattern. As example:
class IRandomPatternGenerator
{
public:
virtual list<int> makePattern(foo bar);
};
class ARandomPatternGenerator : public IRandomPatternGenerator
{
public:
virtual list<int> makePattern(foo bar)
{
...
}
};
class BRandomPatternGenerator : public IRandomPatternGenerator
{
public:
virtual list<int> makePattern(foo bar)
{
...
}
};
Then you can choose particular algorithm depending on runtime type of your RandomPatternGenerator instance. (As example creating list like nicolas78 suggested)
Thank you for all your great input.
I decided to go with function pointers, mainly because I didn't know them before and they seem to be very powerfull and it was a good chance to get to know them, but also because it saves me lot of lines of code.
If I'd be using Ruby / Java / C# I'd have decided for the suggested Strategy Design pattern ;-)
class PatternGenerator{
typedef list<char>(PatternGenerator::*createPatternFunctionPtr);
public:
PatternGenerator(){
Initialize();
}
GetRandomPattern(){
int randomMethod = (rand()%functionPointerVector.size());
createPatternFunctionPtr randomFunction = functionPointerVector.at( randomMethod );
list<char> pattern = (this->*randomFunction)();
return pattern;
}
private:
void Initialize(){
createPatternFunctionPtr methodA = &PatternGenerator::GeneratePatternA;
createPatternFunctionPtr methodB = &PatternGenerator::GeneratePatternB;
...
functionPointerVector.push_back( methodA );
functionPointerVector.push_back( methodB );
}
list<char>GeneratePatternA(){
...}
list<char>GeneratePatternB(){
...}
vector< createPattern > functionPointerVector;
The readability is not much worse as it would have been with the Design Pattern Solution, it's easy to add new algorithms, the pointer arithmetics are capsuled within a class, it prevents memory leaks and it's very fast and effective...