Jason Midkiff
Jason Midkiff

Reputation: 23

C++. Vector of pointers and using the vector

For part of my assignment I need to create a vector of pointers that point to shape objects. I have a few different classes, the base class Shape, and a few derived classes such as Circle and Rectangle. In the main I need to construct the vector and then pass the vector to a function that will expand the dimensions of the shape. So the function will multiply the radius, the length and the width by a certain number. This is my code so far:

vector<Shape*> shapes;
shapes.push_back(circ1);
shapes.push_back(rect1);

with circ1 and rect 1 being objects from the class Circle and Rectangle. I also defined circ1 and rect1 but didnt include the code here.

my function is called expandAll(), this is what i tried to do:

void expandAll(vector<Shape*> shapes, int factor)
{
   for (int i = 0; i < shapes.size(); i++)
   {
      shapes[i] = shapes[i] * factor;
   }
}

This is wrong due to the error that popped up. To sum up, I need help creating a vector of pointers and using that vector in a function. Thanks in advance.

Upvotes: 0

Views: 226

Answers (5)

MarianD
MarianD

Reputation: 14201

Your problem is that you probably tried multiplying the object itself:

shapes[i] = shapes[i] * factor;

In spite of that shapes[i] is the pointer to an object, it is a bad idea.

You have to change (multiply) the properties of the object, so use something as

shapes[i] -> radius = (shapes[i] -> radius) * factor;

or - more compact -

shapes[i] -> radius *= factor;

I don't know the names of the properties of your shapes, so instead or radius use appropriate name or names (as rectangles have both width and hight) and you have decide, too, if the object is of a class Circle or Rectangle.

Upvotes: 0

Roberto V.
Roberto V.

Reputation: 1

void expandAll(vector<Shape*>& shapes, int factor)
{
   for (int i = 0; i < shapes.size(); i++)
   {
      *shapes[i] = *shapes[i] * factor;
   }
}

You should try this thing above.

shapes[i] = shapes[i] * factor; // Here you're multypling pointers, instead of objects you want

Anyway, I think that still wouldn't work if the operator*() on Shape isn't defined.

Upvotes: 0

kebs
kebs

Reputation: 6707

You don't give the code, but I assume this is the classical exercice about polymorphism. So first, assuming you create the circles with Circle circ1, circ2; then you must store their adress in the vector, thus:

vector<Shape*> shapes;
shapes.push_back( &circ1 );
shapes.push_back( &circ2 );

Then, your function should be:

void expandAll( vector<Shape*>& shapes, int factor)
{
   for (int i = 0; i < shapes.size(); i++)
      *shapes[i] = *shapes[i] * factor;
}

But this assumes that your classes all define the * operator, which may not be trivial, if you are a beginner. And its better to pass it as a reference, so the whole vector doesn't get copied.

Upvotes: 0

Sam Varshavchik
Sam Varshavchik

Reputation: 118435

There are multiple problems with the incomplete code you've shown in your question.

shapes is a

vector<Shape*>

Therefore, shapes[i] gives you a Shape *. The shown code is equivalent to:

Shape *p = shapes[i];

shapes[i] = p * factor;

This alternative makes it clear what the problem is. Multiplication of a pointer to some object is completely undefined in C++. There's no such thing.

In C++, you can't multiply a pointer. That's an undefined operation. It makes no sense to multiply a pointer by anything.

What you are most likely trying to do is overload the multiplication operator in your base Shapes class.

However, assuming that your Shapes class has a virtual operator* overload, this still will not work. This is because, as you've described, Shapes is a possibly abstract base class, and, as you know, an abstract class is not assignable/copyable (without an overloaded operator for that, which I think is unlikely here), and if your base class is not abstract, the assignment operator will slice it away. (Not to mention the likely memory leakage).

So, even if Shapes has an overloaded multiplication operator, (*shapes[i]) = (*shapes[i]) * factor; will still fail.

The only way for this approach to work would be if you virtually overload the *= operator, in your abstract base class, and invoke it as

(*shapes[i]) *= factor;

Upvotes: 0

Michael Albers
Michael Albers

Reputation: 3779

shapes[i] is a pointer. Which you can't multiply by factor. You need to dereference the pointer, *shapes[i]. This assumes that your Shape class (and the derived classes) override the * (multiply, not dereference) operator.

And when you fix that, assigning it back to shapes[i] is also going to fail. Likely you'll need to dereference that, too.

Upvotes: 1

Related Questions