Creating an object in the constructor or an init function - c++

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?

You can add a default constructor
CircularBuffer()
{
// set a and b to default values
}

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

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) {}
};

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++.

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

Related

Initializing many private variables in one line

I'm working on legacy code which looks like the following:
class Foo {
public:
Foo();
private:
bool a1, a2, a3 /*, ...*/, a50;
};
Foo::Foo() {
a1 = a2 = a3 /* = ... */ = a50 = false;
}
This is messy. Is there a way to default all private variables of the same time to a single value that's different from the above? I don't want to use an initializer list because there are so many variables.
I know the default constructor of bool assigns false - can this be leveraged?
There are many possible ways to do it, but all of them are very similar. Anyway you will assign each your variable using different forms.
The main method which I think the best is right assign all variables at your constructor line by line. May be its not compact, but it the most meaningful and you allways can easy look your variables default value:
Foo::Foo() {
a1 = false;
a2 = false;
/*...*/
a50 = false;
}
Another method is which you described, with assign operators:
Foo::Foo() {
a1 = a2 = a3 /* = ... */ = a50 = false;
}
And another one allows initialize variables right after constructor declaration:
Foo::Foo() :
a1(false),
a2(false),
/*...*/
a50(true)
{ }
If I forget any method write it to comments, please.
class Foo
{
private:
bool a1{}, a2{}, /*...,*/ a50{};
};
try with this
Foo::Foo (bool aa) : a1 (aa) , a2 (aa), a3 (aa),/*......*/a50(aa){}
You can have another class (in a separate header) which looks like following.
class myBool {
public:
myBool(int x = 1) { _m = x; }
operator bool() const { return 0 < _m; }
private:
int _m;
};
and in your file you can add following
#include "myBool.h"
#define bool myBool
This will initialize all of bool to default value you set in myBool. You may need to add some more methods to myBool class to use it as a full fledge data type. Above is the bare minimum to explain the answer.
Here is an alternative solution to the ones I've seen posted so far, in case it's useful to you.
Put the data you want to mass-initialize to a default false/0 value in its own struct:
struct MyData
{
bool a, b, c, d;
std::string e, f;
};
Now inherit (privately or otherwise) from this struct, and explicitly initialize it in the constructor's initialization list:
class MyClass : private MyData
{
public:
MyClass()
: MyData()
{
}
};
This sets all the bools to false, the strings are empty, any ints become 0, pointers become null, etc, etc
If you forget to put the struct explicitly in the initialization list, some of its members may be uninitialized.
Confirming that it always requires more work to be lazy in c++...
#include <iostream>
#include <utility>
template<class Tuple, std::size_t...Is>
void zero_out_impl(Tuple& t, std::index_sequence<Is...>)
{
using expand = bool[];
(void) expand { false, (std::get<Is>(t) = false)... };
}
template<class...Args>
void zero_out(std::tuple<Args...> t)
{
zero_out_impl(t, std::index_sequence_for<Args...>());
}
struct lots_of_bools {
lots_of_bools()
{
zero_out(std::tie(a,b,c,d,e,f,g,h,i,j));
}
private:
bool a,b,c,d,e,f,g,h,i,j;
};
auto main() -> int
{
lots_of_bools x;
return 0;
}
Here's another way - wrap the bool in a wrapper that default-constructs it.
#include <iostream>
struct auto_false
{
auto_false(bool initial = false) : value(initial) {};
operator bool() const { return value; }
operator bool& () { return value; }
private:
bool value;
};
struct lots_of_bools {
lots_of_bools()
{
}
bool value_of_f() const {
return f;
}
void set_f(bool val) {
f = val;
}
private:
auto_false a,b,c,d,e,f,g,h,i,j;
};
using namespace std;
auto main() -> int
{
lots_of_bools x;
cout << x.value_of_f() << endl;
x.set_f(true);
cout << x.value_of_f() << endl;
return 0;
}
output:
0
1

C++ copying data from an abstract base class pointer?

Let's say you have this:
class foo {
public:
virtual int myFunc() = 0;
///...
virtual bool who() = 0; // don't want to implement this
};
class bar : public foo {
public:
int myFunc() {return 3;}
//...
bool who() {return true;} // don't want to implement this
};
class clam : public foo {
public:
int myFunc() {return 4;}
//...
bool who() {return false;} // don't want to implement this
};
int main() {
std::vector<foo*> vec (2, NULL);
vec[0] = new bar();
vec[1] = new clam();
// copy vec and allocate new ptrs as copies of the data pointed to by vec[i]
std::vector<foo*> vec2 (vec.size(), NULL);
for ( int i=0; i<vec.size(); ++i ) {
// obviously not valid expression, but it would be nice if it were this easy
//vec2[i] = new foo(*vec[i]);
// the hard way of copying... is there easier way?
if (vec[i]->who()) {
vec2[i] = new bar ( * static_cast<bar* >(vec[i]) ) ;
} else {
vec2[i] = new clam( * static_cast<clam*>(vec[i]) );
}
}
return 0;
}
What I want is some simple way of having the compiler look up in its bookkeeping and allocating/copying vec2[i] according to the stored type of *vec[i]. The workaround is to just make a virtual function which basically returns a value specifying what type *vec[i] is, then doing a conditional allocation based on that.
A common approach goes like this:
class foo {
public:
virtual foo* clone() = 0;
};
class bar : public foo {
public:
virtual bar* clone() { return new bar(*this); }
};
class clam : public foo {
public:
virtual clam* clone() { return new clam(*this); }
};
One way you can do it is by using a dynamic cast to determine type of an object such as done here (Finding the type of an object in C++). but the easiest way would probably be to use typeid.
(assuming you want to maintain your way of using type as a determiner, otherwise I would recommend Joachim's or Igor's as better alternatives :) )
you can use the dynamic_cast to downcast and test the type,
bar* pbar = dynamic_cast<bar*>(vec[i])
if (pbar) {
vec2[i] = new bar ( * static_cast<bar* >(vec[i]) ) ;
} else {
vec2[i] = new clam( * static_cast<clam*>(vec[i]) );
}
see for more info in dynamic_cast
http://www.cplusplus.com/doc/tutorial/typecasting/

Partial re-initialization of C++ object through constructor

I am looking for an optimal pattern for partial re-initialization of a C++ object.
With partial re-initialization I mean that some members (step_param in the code example) need to keep its values and other members (value in the code example) are re-init'ed.
Important point: The bloat and redundancy of an init() or reset() member function that does basically the same as the constructor should be avoided.
So far I have the following solution:
namespace reinit_example
{
struct reinit_t {} reinit;
struct stepper_t
{
int step_param; // keep parameter
int value;
stepper_t()
: step_param(1)
, value(step_param)
{}
stepper_t( const stepper_t & c, reinit_t )
: step_param(c.step_param)
, value(step_param)
{}
void step()
{
value += step_param;
}
};
void use_cases_1()
{
stepper_t c;
// use c
c.step();
// and later reinit
c = stepper_t(c,reinit);
}
} // namespace
It should also work well with inheritance and composition:
namespace reinit_example
{
struct stepper_2_t : public stepper_t
{
int step_param_2; // keep parameter
int value_2;
public:
stepper_2_t()
: step_param_2(0)
, value_2(step_param_2)
{}
stepper_2_t( const stepper_2_t & cc, reinit_t )
: stepper_t(cc)
, step_param_2(cc.step_param_2)
, value_2(step_param+2)
{}
void step()
{
stepper_t::step();
value_2 += value + step_param_2;
}
};
struct stepper_comp_t
{
stepper_t c;
stepper_2_t cc;
public:
stepper_comp_t()
{}
stepper_comp_t( const stepper_comp_t & d, reinit_t )
: c(d.c,reinit)
, cc(d.cc,reinit)
{}
void step()
{
c.step();
cc.step();
}
};
void use_cases_2()
{
stepper_2_t cc;
// use cc, change config
cc.step();
// maybe change config
cc.step_param = 2;
// reinit
cc = stepper_2_t(cc,reinit);
stepper_comp_t d;
d = stepper_comp_t(d,reinit);
}
} // namespace
C++11 non-static member initialization makes it even simpler:
#if __has_feature(cxx_nonstatic_member_init)
namespace reinit_example
{
struct stepper_11_t
{
int step_param = 0 ; // keep value
int value = step_param;
stepper_11_t()
{}
stepper_11_t( const stepper_11_t & c11, reinit_t )
: step_param(c11.step_param)
{}
};
void use_cases_3()
{
stepper_11_t c11;
c11 = stepper_11_t(c11,reinit);
}
} // namespace
#endif
For testing:
int main()
{
reinit_example::use_cases_1();
reinit_example::use_cases_2();
#if __has_feature(cxx_nonstatic_member_init)
reinit_example::use_cases_3();
#endif
}
Solution proposed by Jerry Coffin: Parameters are moved into a separate struct, which is passed to the constructor to reinit.
namespace reinit_example
{
struct stepper_config_t
{
struct config_t
{
config_t()
: step_param(1)
{}
int step_param;
int other_param;
};
config_t config;
int value;
stepper_config_t()
: value(config.step_param)
{}
stepper_config_t( const config_t & c)
: config(c)
, value(c.step_param)
{}
void step()
{
value += config.step_param;
}
};
void use_cases_4()
{
stepper_config_t c;
// use c
// and later reinit
c = stepper_config_t(c.config);
}
} // namespace
i believe you should be looking for completely different design pattern.
for example, the "keeper" members should form a full-featured class, while the rest of the members that you don't want to keep would be considered a context of this class (would be another class, used to do some operations on the first class).
this is kind of similar to the flyweight design pattern.

How come a pointer to a derived class cannot be passed to a function expecting a reference to a pointer to the base class?

Sorry for the long title but I did want to be specific.
I expected the following code to work but it doesn't and I can't figure out why :/
#include <cstdio>
#include <cassert>
class UniquePointer
{
public:
void Dispose()
{
delete this;
}
friend void SafeDispose(UniquePointer*& p)
{
if (p != NULL)
{
p->Dispose();
p = NULL;
}
}
protected:
UniquePointer() { }
UniquePointer(const UniquePointer&) { }
virtual ~UniquePointer() { }
};
class Building : public UniquePointer
{
public:
Building()
: mType(0)
{}
void SetBuildingType(int type) { mType = type; }
int GetBuildingType() const { return mType; }
protected:
virtual ~Building() { }
int mType;
};
void Foo()
{
Building* b = new Building();
b->SetBuildingType(5);
int a = b->GetBuildingType();
SafeDispose(b); // error C2664: 'SafeDispose' : cannot convert parameter 1 from 'Building *' to 'UniquePointer *&'
b->Dispose();
}
int main(int argc, char* argv[])
{
Foo();
return 0;
}
Imagine it were legal. Then you could write code like this:
class Animal : public UniquePointer
{
};
void Transmogrify(UniquePointer*& p)
{
p = new Animal();
}
void Foo()
{
Building* b = nullptr;
Transmogrify(b);
b->SetBuildingType(0); // crash
}
Observe that you have violated the type system (you put an Animal where a Building should be) without requiring a cast or raising a compiler error.
I do not think that it is possible to make it work the way you have it designed. Instead, try the following:
template <typename T>
void SafeDispose(T * & p)
{
if (p != NULL)
{
p->Dispose();
p = NULL;
}
}
class UniquePointer
{
public:
void Dispose()
{
delete this;
}
protected:
UniquePointer() { }
UniquePointer(const UniquePointer&) { }
virtual ~UniquePointer() { }
};
It is not allowed because if it were you could do the following:
friend void SafeDispose(UniquePointer*& p)
{
p = new UniquePointer();
}
Building* building;
SafeDispose(building)
//building points to a UniquePointer not a Building.
I guess the work around would be a template function.
To answer the title of your question, you cannot bind a non-const reference to base to a derived class instance because you could then set that reference to a pointer to a base instance that isn't a derived. Consider this function:
void Renew(UniquePointer *& p) {
delete p;
p = new UniquePointer();
}
if you could pass it a pointer to Building you would be able to set it incorrectly to point to a UniquePointer instance.
As it has already been suggested the solution is to change your reference to a plain pointer. Not only this solves your problem, but it is also a better implementation of SafeDispose(); as you wrote it this function gave the false idea that you would always set to 0 all your UniquePointer instances. But what would happen if somebody wrote (assuming UniquePointer constructor was public for simplicity):
UniquePointer *p1 = new UniquePointer();
UniquePointer *p2 = p1;
SafeDispose(p1);
They would expect all of their UniquePointers to be properly taken care of, when p2 is actually invalid.
I guess your SafeDispose should probably look more like :
friend void SafeDispose(UniquePointer** p) ...
In order to invoke it using
SafeDispose(&(UniquePointer*)b);
Then it should work this way.
But your next statement
b->Dispose();
will break cause b should now be NULL, cause it has been disposed and set to NULL by your SafeDispose method.

How exactly would one implement auto update on assignment

Consider the following code:
struct data
{
int foo;
int bar;
};
data a;
a.foo = 200;
a.bar = 300;
static void update(data* a, int rspec)
{
if (!rspec) //my data management
{
3rdPartyApi->CreateStream();
3rdPartyApi->PushData(a->foo);
3rdPartyApi->PushData(a->bar);
3rdPartyApi->CloseStream();
}
else // internal data management
{
3rdPartyApi->CreateStream();
3rdPartyApi->PushData(3rdPartyApi->BufferQueue);
3rdPartyApi->CloseStream();
}
3rdPartyApi->PushStream(3rdPartyApi->GetLastStreamBuffer().POD());
}
Lets say I change the value of a.foo or a.bar, and it requires me to call Update there-after the assignment. Can this be done, without actually calling Update() on each change manually?
[EDIT]
Note that the update function created is also assigned to a function pointer for
the third party API, so it can do it's own internal updating. So making the update function non-global is impossible, and thus is why the current update function is global.
[EDIT]
I also rewrote my example to be more understanding and correct to the actual API I'm using
e.g
3rdPartyApi->StreamUpdate((void (*)(void*, int))update);
Yes, you can. Use class methods for this. Pass a static method from your class to the 3rd party API as an update function.
class data
{
public:
void set_foo(int new_foo);
void set_bar(int new_bar);
int get_foo() const;
int get_bar() const;
// This is the update signature which the 3rd party API can accept.
static void update(void* ptr, int rspec);
private:
// These are private so we can control their access.
int foo;
int bar;
};
void data::set_foo(int new_foo)
{
foo = new_foo;
// 'this' is a special pointer for current data object.
update(this);
}
void data::set_bar(int new_bar)
{
bar = new_bar;
update(this);
}
int data::get_foo() const
{
return foo;
}
int data::get_bar() const
{
return bar;
}
// This is needed if the 3rd party API can only call C bindings.
// If it's a C++ API this is not needed.
extern "C" {
void data::update(void* ptr, int rspec)
{
if (!rspec) //my data management
{
// You have to cast to data* from void*.
data* data_ptr = reinterpret_cast<data*>(ptr);
3rdPartyApi->CreateStream();
3rdPartyApi->PushData(data_ptr->foo);
3rdPartyApi->PushData(data_ptr->bar);
3rdPartyApi->CloseStream();
}
else // internal data management
{
3rdPartyApi->CreateStream();
3rdPartyApi->PushData(3rdPartyApi->BufferQueue);
3rdPartyApi->CloseStream();
}
3rdPartyApi->PushStream(3rdPartyApi->GetLastStreamBuffer().POD());
}
} /* extern "C" */
Then:
3rdPartyApi->StreamUpdate(&data::update);
data a;
a.set_foo(200);
a.set_bar(300);
Note that use of a struct instead of a class is equally fine here. But the convention is to use classes in C++. There is only a minor difference which you can learn later.
It is hard to write code for foo, bar, and data, so let's make it more concrete:
class point
{
public:
int x_coord() const;
int y_coord() const;
void move_to(int new_x, int new_y);
private:
void update_3rd_party();
int x;
int y;
};
void point::move_to(int new_x, int new_y)
{
x = new_x;
y = new_y;
// whatever else needs to be done
update_3rd_party();
}
You need to make use of Observer design pattern or a slight variant of it.
See this example here.
The usual way would be to turn foo and bar into some type that overloads the assignment operator:
class updated_int {
int value;
public:
updated_int(int init = 0) : value(init) {}
updated_int &operator=(int new_val) {
value = new_val;
update();
return *this;
}
// You might want to declare this private and not implement it.
updated_int &operator=(updated_int const &r) {
value = r.value;
update();
return *this;
}
operator int() { return value; }
};
struct data {
updated_int foo;
updated_int bar;
}
data a;
a.foo = 1; // operator= will call update() automatically.