Using pointers and an assignment operator with a derived class in a function that takes an abstract base class as an argument

I have a function (modShape) that takes an abstract base class (Shape) as an argument; inside the function, I want to make a copy of the input object, change the copy and reassign the copy to the input object so that the changes are saved over the scope of modShape.

I created a clone () member function to create the original copy and it seems to work fine. Then I modify the copy using the member function doubleArea () and try to copy it back to the input object.

The base and derived classes are defined in header.h:

#ifndef HEADER_H_
#define HEADER_H_

#include <iostream>
#include <cmath>

using namespace std;

// Abstract base class.
class Shape {
 public:
  // Virtual functions
  virtual double area() { return 0; }
  virtual double perimeter() { return 0; }
  virtual void doubleArea() { /* do nothing */ }
  virtual Shape* clone() const = 0;

};

// Derived class.
class Circle: public Shape {
 private:
  double radius;

 public:
  Circle (double r) : radius(r) {}
  double area() { return (M_PI*pow(radius,2)); }
  double perimeter() { return (M_PI*2*radius); }
  void doubleArea() { radius *= pow(2,0.5); }
  Circle* clone() const { return new Circle(*this); }

};

#endif

The modShape function and test code are in main.cpp:

#include <iostream>
#include "header.h"

using namespace std;

void modShape(Shape &inShape) {

  // Make new Shape* from clone of inShape
  // and double its area.
  Shape* newShape = inShape.clone();
  newShape->doubleArea();
  cout << "newShape area (after doubling): " << newShape->area() << endl;

  // Copy newShape to inShape.
  inShape = *newShape;
  cout << "newShape copied to inShape (circ)." << endl;
  cout << "inShape area in modShape: " << inShape.area() << endl;

};


int main() {

  Circle circ(2);
  cout << "circ initial area (in main): " << circ.area() << endl;
  modShape(circ);
  cout << "circ final area (in main): " << circ.area() << endl;

  return 0;
}

Exiting this function:

mark the start area (mostly): 12.5664

newShape ( ): 25.1327

newShape inShape.

inShape area modShape(): 12.5664

( ): 12.5664

, inShape = * newShape , . , Shape, - (, )? , , , "", , , , . , , , ! .

Update: , - , , . , , :

void modShape2(Shape* inShape) {
  Shape* newShape = inShape->clone();
  cout << inShape->area() << endl;
  inShape = newShape;
  cout << inShape->area() << endl;
}

:

Circle *circ2 = new Circle(1);
cout << "circ2 initial area (in main): " << circ2->area() << endl;
modShape2(circ2);
cout << "circ2 final area (in main): " << circ2->area() << endl;

circ2 ( ): 3.14159

3.14159

6,28319

circ2 ( ): 3.14159

, , modShape2, , modShape2 - . !

+4
1

. , :

inShape = *newShape;

, Shape. , , .

?

, T :

 T& operator= (const T& r);   

.

( , ):

class Shape {
    ...
    virtual void copy(const Shape&r) = 0; 
};

, . :

void copy(const Shape&r) override {
    if (dynamic_cast<const Circle*>(&r)) 
        *this = *dynamic_cast<const Circle*>(&r);
    else throw (invalid_argument("ouch! circle copy mismatch"));
}

-.

+2

Source: https://habr.com/ru/post/1629976/


All Articles