문제

Given this class:

void calculate( int*, int* );

struct A{
    int p;
    int q;
    A() { calculate( &p, &q ); }
};

I want to make the members p and q constant:

struct A{
    const int p;
    const int q;
    // constructor???
};

The question is, how to I initialize those values? I'd like to call calculate, or maybe some kind of proxy function, from within the constructor, but how can I do it in a way to initialize both values at a time? One obvious idea would be a wrapper for the constructor:

A create_A(){
    int p0;
    int q0;
    calculate( &p0, &q0 );
    return A{ p0, q0 };
}

But this leaves me without an appropriate default constructor. Very inconvenient. Is there a way to accomplish this with a default constructor?

Just for fun, I actually found this, which does what I need but isn't really a viable option because it's not thread-safe:

int foo( bool b )
{
    static int p;
    static int q;
    if( b ){
        calculate( &p, &q );
        return p;
    } else {
        return q;
    }
}

struct A{
    const int p;
    const int q;
    A() : p( foo( true ) ), q( foo( false ) ){}
};

EDIT Many people complained about me using const members. But this question is interesting beyond const-members, in my specific use-case p and q are not int but some class-type without a default constructor, so I need to use the member initialization syntax even if they are not const. Oh, and of course const-members do have advantages: faster debug-mode, fewer abstraction layers, less complexity, more compiler enforced invariants.

도움이 되었습니까?

해결책

Return a struct from your helper function, and delegate construction to another constructor, like this:

#include <utility>
std::pair<int,int> calculate();

struct A{
    const int p;
    const int q;
    A() : A(calculate()) {}
private:
    A(std::pair<int,int> a) : p(a.first), q(a.second) {}
};

Delegating constructors are in the standard since C++11, though they worked before in many compilers, as they were a semantically undefined construct.

Still, this disables the assignment-operator. Are you sure inline const-qualified accessors are not a better idea? They have no runtime-overhead.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top