Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling another constructor when constructing an object with const members

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' constness? What's the best solution here?

like image 756
jtbandes Avatar asked Aug 19 '12 23:08

jtbandes


People also ask

Can we call constructor from another constructor in C++?

No, in C++ you cannot call a constructor from a constructor.

Can we make a constructor as const?

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.

Can I call constructor in member function?

Constructor and destructor can also be called from the member function of the class.

How can we initialize an object which is declared as constant data member in another 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.


1 Answers

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)) { }
};
like image 178
ecatmur Avatar answered Sep 24 '22 14:09

ecatmur