문제

나는 C ++에서 일하고 있고 스칼라 값 (예 : double)는 "정의 된"것입니다. 또한 필요한 경우 "undef"를 할 수 있어야합니다.

class Foo {
public:
    double get_bar();

private:
    double bar;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( undefined(bar) )
        calculate_bar();
    return bar;
}

C ++에서 가능합니까?

감사

도움이 되었습니까?

해결책

다른 답변에서 알 수 있듯이 C ++에는이 개념이 없습니다. 그래도 쉽게 작업 할 수 있습니다.

생성자에서 막대를 초기화하는 정의되지 않은 값, 일반적으로 -1.0 또는 유사한 것으로 정의되지 않은 값을 가질 수 있습니다.

Calculate_bar가 음수 값을 반환하지 않는다는 것을 알고 있다면 정의되지 않은 함수를 <0.0에 대한 점검으로 구현할 수 있습니다.

보다 일반적인 솔루션은 바가 아직 정의되었는지 여부를 아직 정의했는지 여부를 말하는 부울을 갖는 것입니다. 생성자에서 처음으로 거짓으로 초기화했으며 처음 설정하면 true로 변경합니다. 부스트 :: 선택 사항 우아한 템플릿 방식으로이를 수행합니다.

이것이 당신이 가진 코드 예제의 모습입니다.

class Foo {
public:
    double get_bar();
    Foo() : barDefined(false) {}
private:
    double bar;
    bool barDefined;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( barDefined == false ) {
        calculate_bar();
        barDefined = true;
    }
    return bar;
}

다른 팁

다른 사람들이 지적했듯이, "정의되지 않은"상태와 같은 것은 없습니다. 그러나 당신은 조사하고 싶을 수도 있습니다 boost.optional

런타임에 의미가 있다면 그런 것은 없습니다. 만약에 bar 초기화되지 않으면 객체가 할당되는 방식에 따라 임의의 비트가 발생하는 모든 것이 있습니다 (일부 할당자는 새로운 메모리를 All-Zero로 초기화합니다).

편집 : 생성자 및/또는 수동 초기화 방법에서 객체 상태를 처리하는 것은 프로그래머에게 달려 있습니다. init()

왜 거짓으로 초기화되는 별도의 플래그를 유지하고 Bar가 계산 될 때 True로 설정 되는가. 그런 다음 플래그를 다시 False로 설정하여 '피해'될 수 있습니다.

if(!isBarValid)
{
    calculateBar();
    isBarValid = true;
}
return bar;

C ++에는 원시 유형에 대한 "정의되지 않은"상태가 없습니다. Float/Double에서 가장 가까운 것은 NAN이지만 실제로는 다른 의미가 있습니다.

이것은 C/C ++에서는 불가능하며, 프리미티브는 항상 할당 된 값 (대부분 의장에서 명시 적으로 할당되지 않는 한 주로 메모리에있는 지점에있는 대부분의 쓰레기)입니다. 나는 사용하지 않은 자리 표시 자 가치 (예 : 포인터의 경우 0)를 가지고있는 것이 일반적이지만, 이들은 명시 적으로 할당되어야합니다. 더블이 어떤 값 으로든 취할 수 있다면, 나는 당신이 그 옆에 부울을 넣고, 처음에는 false에 할당 된 후, 계산을하고 싶을 때 그것을 테스트/설정하는 것이 좋습니다.

여분의 부울을 사용하여해야합니다.

추가 부울을 사용하여 구현하려면 다음 템플릿과 같은 논리를 시도 할 수 있습니다.

template<typename T>
struct Defined
{
 bool defined;
 T value;
 Defined() : defined(false) {}
 Defined(const T& value_) : defined(true), value(value_) {}
 ... and perhaps other operators here ...
 ... to make this behave even more like a T ...
};

당신은 시도 할 수 있습니다 먼저 관용구를 구성하십시오 쓰기 get_bar() 이 방법:

double & get_bar()
{
    static double *bar = new double(something());
    return *bar;
}

전화 할 때 get_bar() 그것은 만들 것입니다 bar 아무도 그것을 요구하지 않았다면 당신을 위해. 후속 통화는 반환됩니다 bar. 링크 된 페이지에서 알 수 있듯이 프로그램이 종료 될 때 OS가 회수되기 때문에 기술적으로 메모리가 유출되지 않습니다.

업데이트:

반환 값을 변경했습니다 double & 수정할 수 있습니다 bar.

초기화 bar 당신이 호출 할 때 결코 발생할 수없는 값으로 something() 생성자에서 기능.

예를 들어:

Foo(): bar(-1)
{
}

그런 다음 값을 확인하십시오 -1 에서 get_bar 기능.

(hmmm Laserallan은 또한 1 분 전에 그 대답을 게시했습니다 :-( ;-))

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