2015-01-22 3 views
-5

C++의 새로운 기능입니다. 나는 c_str() 함수를 구현하려고합니다. 나는 시도했다 :사용자 정의 문자열 구현에서 c_str() 함수의 제약 문제가 발생했습니다.

class Str 
{ 

public: 
    typedef size_t size_type; 
    typedef char* iterator; 
    typedef const char* const_iterator; 

const char* c_str() const { 
    char* tmp = alloc.allocate(length + 1); 
    alloc.construct(tmp + length + 1, '\0'); 
    for(size_type i = 0; i < length; ++i) 
     tmp[i] = data[i]; 

    return tmp; 
} 

private: 
    char* data; 
    size_type length; 

    std::allocator<char> alloc; 
}; 

그러나 컴파일러는 불평하고있다. const로 함수를 정의하기 때문에 allocate()는 const 포인터를 반환해야합니다 (또는 뭔가 잘못 됐습니다). 어쨌든, 이것은 작동하지 않으며 나는 무엇이 사실인지 알고 싶다.

1) 나는 allocate()를 호출한다는 것을 알고 있지만, Str의 멤버가 아니라 새로운 변수를 호출한다. 그래서 나는 그 부분을 얻지 못합니다.
2) "데이터 반환"에 대해 알고 있지만 왜 이것이 작동하지 않는지 알고 싶습니다. C++ 11에서는 c_str()과 data() 사이에는 아무런 차이가 없지만 여전히 그렇다고 가정 해 봅시다. 항상 "데이터 반환"을 수행하면 어떻게이 두 함수간에 차이가 있습니까?

+6

무엇이 오류입니까? –

+2

당신의 함수가'const'이기 때문에'const.allocate'와 같이 멤버에 non-const 메소드를 호출 할 수 없습니다. – BeyelerStudios

+6

이 메소드는'const'이지만'alloc.allocate'와'alloc.construct'를 호출합니다. 이들은 비 const입니다. 너는 그렇게 할 수 없다. 하지만 어쨌든 당신의 기능의 요점은 보이지 않습니다. scring 클래스가 할당 된 문자열을 호출자에게 반환하려는 이유를 알 수 없습니다. 특히 호출자가 할당을 취소하는 방법을 모르는 경우에는 특히 그렇습니다. 오류를 "수정"하고 싶지 않은 경우에는 다른 접근 방식이 필요합니다. – juanchopanza

답변

6

c_str()std::string의 알려진 모든 구현에 의해 수행되는 방법은 data 하나 개 추가 문자위한 공간을 예약하고 c_str() 단순히 return data; 수 있도록이 널 (null), 항상 종료 유지하는 것입니다 그것은 이미 보장되어 널 종료.

const로 함수를 정의했기 때문에 allocate()가 const 포인터를 반환해야합니다 (또는 잘못된 것이 있습니다).

아니요, 분명히 잘못된 것입니다.

코드의 문제는 alloc이 해당 구성원 함수에서 const입니다. 그것은 메모리 당신이 그것을 호출 할 때마다 할당하기 때문에,이 함수가 정확하지 않습니다

const char* c_str() const { 
    std::allocator<char> alloc2(alloc); 
    char* tmp = alloc2.allocate(length + 1); 
    alloc2.construct(tmp + length + 1, '\0'); 
    for(size_type i = 0; i < length; ++i) 
     tmp[i] = data[i]; 

    return tmp; 
} 

, 그래서 std::allocator<char>를 사용하여 호출자는 해제해야합니다 : 당신은 할당의 const가 아닌 복사를하여 해결할 수 있습니다 즉 이 아니며 올바른 인터페이스는 c_str()입니다!

N.B. std::allocator<char>::construct을 사용하는 것은 완전히 무의미합니다. tmp[length] = '\0'을 수행 할 수도 있습니다. std::allocator<char>을 사용해도 무의미합니다. newdelete[]을 사용할 수 있습니다. 할당자를 사용하는 이유는 사용자가 대체 할당자를 사용하여 사용자 정의 할 수 있도록 허용하는 것이지만 std::allocator<char> 만 사용하도록 수정하려는 경우 할당자를 전혀 사용하지 않는 것이 좋습니다. 그러면 클래스를 만드는 것입니다. 무의미한 alloc 회원을 저장하기 위해 더 많은 공간을 차지하십시오.

또한 tmp + length일까요?

alloc.construct(tmp + length + 1, '\0'); 

편집 된 질문에 응답 :

1) 나는() 할당 전화를 알고,하지만 난 str을 아닌 멤버, 새로운 변수를 호출합니다. 그래서 나는 그 부분을 얻지 못합니다.

어머, 아니, 회원에게 부르세요!

2) "반환 데이터"에 대해 알고 있지만 왜 이것이 작동하지 않는지 알고 싶습니다. C++ 11에서는 c_str()과 data() 사이에는 아무런 차이가 없지만 여전히 그렇다고 가정 해 봅시다. 항상 "데이터 반환"을 수행하면 어떻게이 두 함수간에 차이가 있습니까?

왜 둘 사이에 차이를 만들고 싶습니까?

C++ 03 둘 사이에 차이가있을 수 있어야 말을하지 않습니다

, 그것은 그들이 동일해야하는 준수하고 이유 중 하나 c_str()data()는 C++ 11 입니다 정확히 동일한 것 이것이 모든 구현이 C++ 03에서 수행 한 방법입니다. 어쨌든. 정말 유일한 방법입니다.

아무 이유없이 서로 다르게 설정하면 c_str()을 구현하는 것이 매우 어렵 기 때문에 매우 어리석은 디자인을 선택합니다.

+0

1) allocate()는 길이의 값을 취해 비 const 포인터를 반환 할 것이라고 생각했습니다. 그래서, 나는 그것이 길이의 가치를 변화시키지 않을 것이라고 생각했습니다. 2) null 종결 const char * 및 null (null)로 끝나는 const char *를 반환하는 data()를 반환하기 위해 c_str()이 구현되었습니다. – Bade

+0

또는 alloc 멤버를 변경하는 것에 대해 이야기하고 있습니까? 이것에 관해서는 유감 스럽습니다. – Bade

+0

** ** alloc :: allococate (length + 1);'이 ** ** 클래스 ** 멤버 인'alloc'에 ** const가 아닌 ** 함수를 호출합니다. ** 그래서 당신 const 멤버 함수에서 const가 아닌 것들을 할 수 없어! –

0

왜 데이터를 const char *로 반환하지 않습니까? const 이후 아무도 그것을 바꿀 수 없다.

const char* c_str() const{ 
    return data; 
} 
+2

정확하고 유효한 제안, 더 나은 의견입니다. –

+0

죄송합니다. 귀하의 답변은 실제로 질문에 대답하지 않습니다. 질문이 "해당 사실을 알고 싶습니다"라고 가정하십시오. – quetzalcoatl

+1

OP가 null 문자를 사용하여 '데이터'를 종결하지 않는 한 그럴 가능성이 큽니다. 이 경우 반환 된 포인터를 사용할 수 없습니다. – SirDarius

관련 문제