I have a class with const
members, and one constructor which calls another constructor with extra values filled in. Normally I could use a colon initializer for this, but the function is complex (printf
/sprintf
-like) and requires me to use a variable on the stack, so I have to do this in the body of the constructor and use assign *this
to the new object. But of course this is invalid, because my member variables are const
.
class A
{
public:
A(int b) : b(b), c(0), d(0) // required because const
{
int newC = 0;
int newD = 0;
myfunc(b, &newC, &newD);
*this = A(b, newC, newD); // invalid because members are const
// "cannot define the implicit default assignment operator for 'A', because non-static const member 'b' can't use default assignment operator"
// or, sometimes,
// "error: overload resolution selected implicitly-deleted copy assignment operator"
};
A(int b, int c, int d) : b(b), c(c), d(d) { };
const int b;
const int c;
const int d;
};
A a(0);
(I haven't explicitly deleted the assignment operator.) I declared the members const because I would like them to be public, but not mutable.
Is there some canonical way of solving this problem without using scary casts and force-overriding the members' const
ness? What's the best solution here?
No, in C++ you cannot call a constructor from a constructor.
The choice of which version to use is made by the compiler based on whether or not the object used to call the member function is constant. Constructors and destructors can never be declared to be const . They are always allowed to modify an object even if the object itself is constant.
Constructor and destructor can also be called from the member function of the class.
To initialize the const value using constructor, we have to use the initialize list. This initializer list is used to initialize the data member of a class. The list of members, that will be initialized, will be present after the constructor after colon. members will be separated using comma.
You can add a parameters class and use either C++11 constructor delegation or a base class:
struct parameters {
int b; int c; int d;
parameters(int b): b(b), c(), d() {
myfunc(b, &c, &d);
}
};
// constructor delegation
class A {
public:
A(int b): A(parameters(b)) { }
A(parameters p): b(p.b), c(p.c), d(p.d) { }
};
// base/wrapper
class ABase {
ABase(parameters p): b(p.b), c(p.c), d(p.d) { }
};
class A: public ABase {
public:
A(int b): ABase(parameters(b)) { }
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With