dylan
dylan

Reputation: 289

How to define a default constructor that creates the previous object

For example if I define a point object (2,3) and then use the default constructor to declare another point that would result in a point object (2,3). Then If I were to create another point object (5,6) the default constructor would change to produce point objects (5,6). Here is my attempt:

point.h

#ifndef POINT_H
#define POINT_H

int point::previousX = 0;
int point::previousY = 0;

int defualtX = previousX;
int defualtY = previousY;

struct point{
    point(int newX = defualtX, int newY = defualtY) 
    : x(previousX = newX), y(previousY = newY){;};
    ~point(void){;};
    static int previousX;
    static int previousY;
    int x, y; 
};

#endif//POINT_H

There is an obvious problem in this code. The class point has not been defined before the "previous" and "defualt" variabes; therefore, the definition of previousX and previousY will not work. I could move the "defualt" and "previous" variables below the class definition, but then the point constructor will not work.

Upvotes: 2

Views: 179

Answers (4)

WorldSEnder
WorldSEnder

Reputation: 5044

You could defer the default initializations into free-standing functions like this:

namespace _detail {
  int getDefaultX();
  int getDefaultY();
}

struct point{
    static int previousX;
    static int previousY;

    point(int newX = _detail::getDefaultX(),
          int newY = _detail::getDefaultY());
    ~point();
    int x, y;
};

// in the .cpp file:


point::point(int newX, int newY)
  : x(previousX = newX), y(previousY = newY){;}
point::~point() {}

namespace _detail {
  int getDefaultX() {
    return point::previousX;
  }
  int getDefaultY() {
    return point::previousY;
  }
}
int point::previousX = 0;
int point::previousY = 0;

Upvotes: 0

Jarod42
Jarod42

Reputation: 217085

Just declare in correct order:

struct point{
    point(int newX = previousX, int newY = previousY) 
    : x(previousX = newX), y(previousY = newY){}

    void print() const { std::cout << x << ", " << y << std::endl; }

    static int previousX;
    static int previousY;
    int x, y; 
};

Live Demo

Upvotes: 0

&#193;lvaro Mart
&#193;lvaro Mart

Reputation: 1

Why don't you just pass the previous values to the constructor?

#ifndef POINT_H
#define POINT_H

class Point
{
public:
Point(int newX, int newY)
{
  x = newX;
  y = newY;
}
int getX() {return x;}
int getY() {return y;}
~Point(){};
private:
int x, y; 
};

#endif//POINT_H

Something like Point oldP(3,3) and Point newP(old.getX(),old.getY())

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

The class point has not been defined before the "previous" and "default" variables; therefore, the definition of previousX and previousY will not work

It wouldn't work anyway, because you placed the definitions into a header file. This is incorrect: definitions must be placed in a cpp file in order to avoid doubly-defined errors during linking.

Moving the definitions into a cpp file will fix the first compile problem, but the second problem would remain: you cannot use defaultX and defaultY variables as default parameter values in the way shown in your code, because even if you could copy previousX and previousY into defaultX and defaultY, this would be a one-time copy; all calls to point's constructor would use zero values, copied into defaultX and defaultY at initialization.

You can solve this by adding two constructors - with no parameters, and with a single parameter, like this:

point() : x(previousX), y(previousY) {}
point(int x) : x(x), y(previousY) {}

Demo.

Note: I would strongly recommend against using a solution that relies on values of static variables for initialization, because it relies on the order in which constructors are executed, and breaks spectacularly in concurrent systems.

Upvotes: 2

Related Questions