0

How do I make it so I dont have to manually delete the pointer?

With unique_ptr in the vector<> ?

Here is my code:

class vec2 {
 public:
  double x;
  double y;

  vec2() {
    x = 0.0;
    y = 0.0;
  }

  vec2(double xx, double yy) {
    x = xx;
    y = yy;
    cout << "constructor called" << endl;
  }

  ~vec2() {
    static int count = 0;
    cout << "destructor " << count << endl;
    count++;
  }

  virtual double Length() { return sqrt(x * x + y * y); }

  bool operator==(vec2& v) { return x == v.x && y == v.y; }

  virtual string toString() {
    stringstream s("");
    s << "[" << x << " " << y << "]";
    return s.str();
  }
};

int main() {
  vector<vec2*> vecs;
  vecs.push_back(new vec2(1.8, 1.7));
  vecs.push_back(new vec2(1.99, 1.7));
  for (vec2* v : vecs) {
    cout << v->toString() << endl;
    delete v;
  }
}

http://www.xgdev.com/notepad/textfiles/37631a.txt

Evg
  • 25,259
  • 5
  • 41
  • 83
user366866
  • 55
  • 1
  • 4
  • 7
    how about not using pointers and making it a `std::vector`? – Thomas Aug 25 '18 at 07:13
  • if i do it plain vec2 it is slower and constructor and destructor gets called more times, less efficient. – user366866 Aug 25 '18 at 07:15
  • @Thomas, probably `virtual` methods are there for a reason. – Evg Aug 25 '18 at 07:17
  • there is a vec3 class too, but I didnt include it. vec3 inherits from vec2 – user366866 Aug 25 '18 at 07:38
  • @Evgeny missed that. but there prob. is no need for it. ... the OP should make his destructor virtual then ... – Thomas Aug 25 '18 at 08:09
  • @Thomas, totally agree. There should be no inheritance from `vec2` and no `virtual`s. But that's another question. – Evg Aug 25 '18 at 08:54
  • @user366866: have you _measured_ the performance difference? Copying two doubles is a breeze compared to heap allocation and bad locality you get by having allocations scattered around. – Matteo Italia Aug 25 '18 at 09:16
  • 1
    You will actually be faster when using vector instead of using pointers. What makes your pointers slow is that you allocate a new one for every item in the vector. This is very bad for memory layout, your pointers will end up being all over the place, resulting in cache misses. A straight linear layout, like you get with vector will be much faster and even easier to maintain. – gonutz Aug 25 '18 at 09:28

1 Answers1

2

Simple:

std::vector<std::unique_ptr<vec2>> vecs;
vecs.reserve(2);   // Optional
vecs.push_back(std::make_unique<vec2>(1.8 ,1.7));
vecs.push_back(std::make_unique<vec2>(1.99, 1.7));
for (auto& v : vecs) {
    cout << v->toString() << endl;
}

If you have virtual member function(s), most probably, destructor should also be virtual.

Evg
  • 25,259
  • 5
  • 41
  • 83
  • is the copy constructor called? – user366866 Aug 25 '18 at 07:44
  • @user366866, no. – Evg Aug 25 '18 at 07:47
  • how about using `emplace_back` and reserving? – Thomas Aug 25 '18 at 12:52
  • 1. `reserve` - probably, yes. 2. If `std::make_unique` is used, `emplace_back` and `push_back` are equivalent (for example, in Microsoft STL the overload of `push_back` taking `T&&` simply calls `emplace_back`), `emplace_back` can be used with `new`: `emplace_back(new vec2(1, 2))`, but `make_unique` is better, https://stackoverflow.com/questions/22571202/differences-between-stdmake-unique-and-stdunique-ptr – Evg Aug 25 '18 at 13:40