0
#include <iostream>
using namespace std;

class Point {
    int x, y;
public:
    Point ():x(0),y(0){};
    void setX (int xx){x = xx;};
    void setY (int yy){y = yy;};
    int getX (){return x;};
    int getY (){return y;};
};

class Polygon {
    int n;
    double degree;
    Point* vertex;
public:
    Polygon (int nn):n(nn){
        degree = 360.0 / n;
        //vertex = new Point [n];
    };
private:
    vertex = new Point [n];
};

so I'm trying to declare vertex array using new, but I keep getting this error: data member initializer is not allowed

is 'new' considered initializing?! and I tried doing it in constructor but I think it'll only work in constructor's scope.

I'm also confused about this: n should be initialized before using new, so will this be solved if I just write the declaration after constructor?

Zohal
  • 25
  • 5
  • 3
    1. Use `std::vector vertex;` 2. If you cannot, then initialize `vertex` in the initializer list: `Polygon(int nn): n(nn), vertex(new Point[nn]) {...` 3. If you manage a resource, you'll need at least a custom copy constructor, copy assignment operator, and destructor (rule of 3) and if necessary a move constructor and move assignment operator in addition (rule of 5). – JohnFilleau Jul 06 '20 at 20:53
  • You can't initialize a variable at class scope. The version where you do it in the constructor [compiles](https://godbolt.org/z/QUpwdR). – cigien Jul 06 '20 at 20:54
  • `I think it'll only work in constructor's scope.` That's not true, and if you do think that then why don't you think the same about `degree`? Newbies often get confused about pointers and think special rules apply to them when in fact they don't. Just initialise member variables, whether pointers or non-pointers, in the constructor. – john Jul 06 '20 at 20:56
  • @JohnFilleau thank you very much, things u said worked. – Zohal Jul 06 '20 at 21:03
  • @john it's great if thats the case, yeah I'm kinda a newbie. thank u. – Zohal Jul 06 '20 at 21:03
  • 2
    @Zohal if you don't know the rule of 3, please [read up on it](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). Otherwise you'll experience strange bugs you can't explain when two `Polygon`s start sharing the same `Point` array. – JohnFilleau Jul 06 '20 at 21:04
  • 1
    @cigien "*You can't initialize a variable at class scope*" - actually, you can, in C++11 and later. But it has to be done in the variable's declaration, not in a separate statement, as the OP's example is trying to do. But in this case, that won't work, since the value of `n` is not known until the constructor is called. – Remy Lebeau Jul 06 '20 at 21:27
  • @RemyLebeau True, I meant *"... the way you tried to do it"*. I'll leave the comment, it should be understandable from the question's context. – cigien Jul 06 '20 at 21:32
  • Independent recommendation: There is no need to make the members of `Point` private, just do sth like `struct Point {int x=0, y=0; };` – chtz Jul 13 '20 at 08:25

1 Answers1

0
class Point {
public:
    Point ():x(0),y(0){};
    void setX (int xx){x = xx;}
    void setY (int yy){y = yy;}
    int getX (){return x;}
    int getY (){return y;}
//change access level to 'private'.
private:
    int x;
    int y;
};

class Polygon {
public:
    Polygon (int nn):n(nn){
        degree = 360.0 / n;
        vertex = new Point [n];
    }
    // deallocate memory from heap
    ~Polygon () {
        delete [] vertex;
    }
    // overload copy constructor to avoid double free 
    Polygon (const Polygon& pg) : n(pg.n), degree(pg.degree) {
        vertex = new Point [n];
        for (int i = 0; i < n; i++) {
            vertex[i] = pg.vertex[i];
        }
    }
    // overload assignment operator to avoid memory leak
    Polygon& operator=(const Polygon& pg) {
        if (this != &pg) {
            n = pg.n;
            degree = pg.degree;
            delete [] vertex;
            vertex = new Point[n];
            for (int i = 0; i < n; i++) {
                vertex[i] = pg.vertex[i];
            }
        }
        return *this;
    }
    // use pointer to change/get the value.
    Point* get_vertex() {
        return vertex;
    }
//change access level to 'private'.
private:
    int n;
    double degree;
    Point* vertex;
};
Anna
  • 261
  • 1
  • 2
  • 12
  • 1
    Code just dumped without explanation is not terribly helpful. What was wrong? What did you change? How did that resolve it? – underscore_d Jul 07 '20 at 09:48
  • You should also just use `std::vector` instead of `new` (there is barely any use-case for plain-`new` in modern C++). – chtz Jul 13 '20 at 08:28
  • Yeah. Vector is a better choice. It was just an example for the question. – Anna Jul 13 '20 at 08:41