Creating an object in the constructor or an init f

2019-08-30 02:03发布

问题:

I have defined a class like this:

 class CircularBuffer {
   private:
     struct entry {
       uint64_t key;
       int nextPtr;
       int prevPtr;
       int delta;
     };

     int head, tail, limit, degree;
     entry *en;
   public:
     CircularBuffer(int a, int b)
     {
       limit = a;
       head = 0;
       tail = limit -1;
       degree = b;
       en = new entry[ limit ];
       for (int i=0; i<limit; i++) {
         en[i].key = 0;
         en[i].delta = 0;
         en[i].nextPtr = 0;
         en[i].prevPtr = 0;
       }
     };
     ~CircularBuffer() { delete [] en; }
  };

And in another file I have included this class (the header file)

 #include "circular.h"
 class foo {
    CircularBuffer cb;
    foo() {}   //ERROR LINE
    void initialize() {
       cb = new CircularBuffer(10, 2);
    }
 };

However this has error which says:

 error: no matching function for call to ‘CircularBuffer::CircularBuffer()’
 note: candidates are: CircularBuffer::CircularBuffer(int, int)
 note:                 CircularBuffer::CircularBuffer(const CircularBuffer&)

and it forces me to do like this:

 #include "circular.h"
 class foo {
    CircularBuffer cb;
    foo()
      : cb( CircularBuffer(10, 2) )
    {}

    void initialize() {}
 };

However I don't want the second implementation. I want the first one. How can I fix that?

回答1:

You can add a default constructor

CircularBuffer()
{
    // set a and b to default values
}


回答2:

Just define cb as a pointer

#include "circular.h"
 class foo {
    CircularBuffer * cb;
    foo() {}   //ERROR LINE
    void initialize() {
       cb = new CircularBuffer(10, 2);
    }
 };

And don't forget to delete cb; somewhere to not leak your memory



回答3:

This should be possible

#include "circular.h"
class foo {
    CircularBuffer cb;
    foo() {}
    void initialize() {
        cb = CircularBuffer(10, 2);
    }
};

The problem with your version was that you were using new, which returns a pointer, but the member variable cb is not a pointer.

However, the best way would be

#include "circular.h"
class foo {
    CircularBuffer cb;
    foo() : cb(10,  2) {}
};

Or, if you want to pass parameters to the constructor

#include "circular.h"
class foo {
    CircularBuffer cb;
    foo(int a, int b) : cb(a,  b) {}
};


回答4:

and it forces me to do like this:

...
foo()
  : cb( CircularBuffer(10, 2) )
{}
...

However I don't want the second implementation. I want the first one. How can I fix that?

It does not force you to this, but rather to this:

: cb(10, 2)

And this is how you initialize in C++. Everything coming after the opening { is assignment, not initialization.

The "fix" is to use initialization rather than assignment for initialization. There's not much to love or hate about, this is C++.



回答5:

It gives you an error because cb is not a pointer and you are using "new".

But BTW... the constructor initialization is more efficient :D



标签: c++ class