-2

I'm new to learning C++ am now especially learning about polymorphism and inheriatance, so pardon my following question, which I'm not sure if its possible? If not please advice on what I should do instead.

I have a parent class that stores the following:

ShapeTwo (string, bool, int, int)

And I have two classes (Square and Rectangle) deriving from the parent class. And I have managed to push my sub-classes into this vector: vector<ShapeTwo*> objs;

objs.push_back(new Square(square));
objs.push_back(new Rectangle(rectangle));

so now my objs.size() = 2, since there are 2 ShapeTwo in there now.

Right now I'm stuck at figuring out how to loop it in a way that it will print out every individual type stored in each element in the class vector. The program can compile and run, but the results are not expected.

//loop to print out each shape details
for(int i = 0; i < objs.size(); i++)
{
    cout << "Shape no. :" << objs.at(i) << endl;
    cout << "Name :" << objs[i] -> getName() << endl;
    cout << "Bool type :" << objs[i] -> getWarpSpace() << endl;
    cout << endl;
}

//results
Shape no. :0x9363a60
Name :
Bool type :

Shape no. :0x9363ae0
Name :
Bool type :

It's printing out some weird characters when I'm just trying to print out the position of the vector. And the other values I'm trying to get is not printing out. How do I check if my vector has the correct values stored?

Please help.

Edited to include Declarations

ShapeTwo.h
class ShapeTwo
{
protected:
    string name, specialType;
    bool containsWarpSpace;

public:
    ShapeTwo();
    ShapeTwo(string, bool);

    string getName();
    void setName(string);
    void setWarpSpace(string);
    string getWarpSpace();
};

class Square:public ShapeTwo
{
public:
    Square();
    Square(string, bool, int, int);
};

class Rectangle:public ShapeTwo
{
public:
    Rectangle();
    Rectangle(string, bool, int, int);
};

Edited to include Definitions

void ShapeTwo::setName(string name)
{
    this -> name = name;
}

string ShapeTwo::getName()
{
    return (name);
}
M.TwT
  • 73
  • 7
  • Include the declaration of your base shape class as well as your rectangle and square classes, looking at what you posted I am seeing some major design flaws. – vividpk21 Aug 21 '18 at 08:07
  • @vividpk21 I have included the declarations! What flaws do you think? – M.TwT Aug 21 '18 at 08:21
  • I listed everything I can think of in my answer, the reason you have downvotes is because it doesn't seem like you know what you're doing. I you are actually making an effort to learn thats perfectly acceptable, but you need to learn the basics first. – vividpk21 Aug 21 '18 at 08:26
  • when you want polymorphism then you usually dont care what is the actual type of the objects, but you only access them via their common interface (ie that of the base class). If thats not the case, then why do you want polymorphism in the first place? – 463035818_is_not_an_ai Aug 21 '18 at 08:55
  • 1
    please include a [mcve]. Its rather hard to make sense of your code fragments – 463035818_is_not_an_ai Aug 21 '18 at 08:58
  • Or rather, your code fragments make some sense, but they are not enough to figure out why things aren't working - the problem is not (or not only) in the code you posted. Give us the smallest complete code that can be compiled and executed to produce your observed behavior and you will have your question answered in no time. See [MCVE] for how to do that. – Max Langhof Aug 21 '18 at 09:17
  • Where is/are the definition(s) of getName (I can see a declaration of a non-virtual function but no definitions). (also what is ShapeTwoD()? it's not a constructor of ShapeTwo ) – ROX Aug 21 '18 at 10:47
  • @ROX sorry its just ShapeTwo. Thank you for the alert, I have edited it to be just ShapeTwo. But my program is all right with the naming. I have also edited my question to include my getName() definitions above. – M.TwT Aug 21 '18 at 14:39
  • I think you would get better answers if you kept your question focused. As it stands, there are at least two separate questions being asked: how to get a variable type (if it is possible), and how to check the values in a vector. Which of these is the one you want an answer to? It's not clear what is the question and what is the background info. Try writing your post so that is starts with the context (e.g. you have two classes `C` and `D`, each derived from `A`), then proceed to the question. It's often good to follow that with your motivation / what you hope to accomplish, but stay focused! – JaMiT Aug 22 '18 at 22:07
  • @JaMiT thank you for your advice. I have amended my question accordingly! – M.TwT Aug 23 '18 at 01:47

2 Answers2

0

I guess the actual question is the following:

How do I check if my vector has the correct values stored?

  1. Using an IDE: Unless you are using a simple text editor to write your code and compiling from a command prompt, you are probably using an integrated development environment (IDE). Most IDEs come with debugging tools that you would benefit greatly from learning. Among these is usually a way to tell the program to pause when it hits a certain line of code. While the program is paused, there is usually a way to inspect the values of variables. Once you know how to use these tools, they will help you debug your programs much faster than asking here.

  2. Self-logging: If you are not using an IDE, you may find it useful to write a method in your objects that will write their contents to a stream. Then you could get useful debugging output from a statement like cout << *objs[i]; (note the asterisk, as you want the object that objs[i] points to, not the pointer itself). An advantage of this approach is that your logging can be more accurate, without the surrounding code making assumptions about which (derived) objects are present. I'll give an example of how to do this later, so it doesn't interrupt this list too much.

  3. Ad hoc logging: For a quick sanity check of your code, you could do pretty much what you are doing: write various bits of data from the object to an output stream. A big drawback of this is that if the object's data is vastly different from what you think it is, you might get totally confused by the output. [Speaking of which, I think you got totally confused by the output. The only outright mistake I see in your attempt to log information is that the position in the array (shape number) is your loop's control variable (i), not the pointer at that position (objs.at(i)). Pointers tend to get printed in hexadecimal, as in 0x9363a60, and the exact value tends to be uninformative (outside some special cases).]

In summary, I think you did check the values in your vector and discovered that the values are not what you intended. It appears that your objects' names and warp spaces are empty strings, yet you were expecting some content in them. Your next step might be to up your debugging game by moving to option 1 or 2.


So how could one implement self-logging? I would first recommend an IDE. However, someone at some time might find this answer and for whatever reason be unable to use an IDE. So I'll throw together an example. Please understand that the code snippets that follow might contain errors -- they are intended merely to point you in the right direction. Also please understand that this is only one approach among several that could be taken.

I'll use the setting from the question. There is a base class called ShapeTwo and derived classes Square and Rectangle. First, I might declare a friend of the base class to handle the desired interface (operator<<). Add to that a pure virtual function to handle the actual streaming:

class ShapeTwo
{
    // Existing declaration goes here
private:
    friend std::ostream& operator<<(std::ostream&, const ShapeTwo&);
    virtual std::ostream& to_stream(std::ostream&) = 0;
};

Then I would override the pure virtual function in the most-derived classes. For example, the version in the Rectangle class might look like the following. (Details of course may differ depending on how you store your rectangles.)

std::ostream& Rectangle::to_stream(std::ostream& os)
{
    return os << "rectangle from " << x1 << ',' << y1 << " to " << x2 << ',' << y2;
}

The idea here is to make it easy to do the right thing with regards to logging each class. You have the convenience of a member function, and the compiler will warn you if you forget to define it for any of the instantiated classes. You only have to mess with a friend in the base class. Speaking of the friend, that function would need to be defined somewhere. It might look like the following.

std::ostream& operator<<(std::ostream& os, const ShapeTwo& obj)
{
    return obj.to_stream(os);
}

So that's the gist of it. If you can't use an IDE for deugging, you might find it useful to be able to stream your objects and not worry about which details to stream while you're trying to debug something else. The above gives one way to do that.

JaMiT
  • 14,422
  • 4
  • 15
  • 31
-2

Lets see:

cout << "Name :" << objs[i] -> getName() << endl;
cout << "Bool type :" << objs[i] -> getWarpSpace() << endl;

If the above prints are really giving you blank values this means you have not set the variables within your class, or you have made a void return function so learn about functions here: Difference between void and non-void functions in C++

objs.push_back(new Square(square));
objs.push_back(new Rectangle(rectangle));

I honestly have no idea what these are doing, but it seems like you need to learn how to declare constructors, which can be found here: Different ways of using C++ constructors and here: C++ Constructor which will also help with the variables you haven't set.

Because when I tried to display the vector values with this code: cout << objs[i] << endl; it just gives me the result 0x9363ae0

So that number that is displayed is called a pointer and you can find more about it here: https://www.learncpp.com/cpp-tutorial/6-8a-pointer-arithmetic-and-array-indexing/ which also encompasses array indexing which you need to learn as well.

vividpk21
  • 384
  • 1
  • 11
  • 2
    Yes it is homework. And I thought this may be the best site to ask for help as I'm just a learning student. I appreciated your help! I have read about the void return function, but the functions I called above are not void? my `getName() is string` and `getWarpSpace() is string` I will try to research and study more. Thanks for the help. – M.TwT Aug 21 '18 at 08:44
  • No problem, I see how people would've taken what I said negatively but I'm trying to help. – vividpk21 Aug 21 '18 at 09:01