Unique_ptr выходит за рамки - PullRequest
       5

Unique_ptr выходит за рамки

1 голос
/ 09 февраля 2020

У меня проблема с передачей unique_ptrs функциям, кажется, что они go выходят за рамки, когда я перехожу к askQuestion.

слышит мой код.

char askQuestion(string *questions[8], unique_ptr<binaryBase>answered) {
    bool asked = false;
    char input = '0';
    while (!asked) { // loop until you find a question that has not been asked
        int randomQuestion = (rand() % 8); // generate a random number
        if (!(answered->getBit(randomQuestion))) { // check if the question has been answered 
            getInput(input, *questions[randomQuestion]);
            answered->toggleBit(randomQuestion);
            asked = true;
        }
    }
    return input;
}

эти два доступ к функциям unique_ptrs, функция ниже полагается на функцию выше для ввода. когда я вызываю askQuestion, я получаю "(переменная) не может быть ссылка - это удаленная функция"


bool checkAnswer(char answer, int place, binaryBase* reference) {
/*  if the answer is T and the correct answer is true, returns true
    if the answer is F and the correct answer is false, returns true
    return false otherwise
*/ return((answer=='T'&&reference->getBit(place))||(answer=='F'&&!reference->getBit(place)));
}

binaryBase является простым пользовательским классом и имеет только 8 int в качестве данных и получателей и установщиков для битов , это обрабатывает 8-битный int как байт для хранения «логических» ответов для программы.

Ответы [ 2 ]

2 голосов
/ 09 февраля 2020

Я не вижу звонка на askQuestion() в вашем примере. Однако я вижу, что askQuestion() является «наблюдателем» параметра answered. Unique_ptr используется для передачи владения указателем, а не только для его наблюдения. Поэтому вы должны определить эту функцию следующим образом:

char askQuestion(string *questions[8], binaryBase& answered)

. Используйте здесь ссылку вместо указателя, чтобы было ясно, что передача пустого значения недопустима. (Конечно, измените все вхождения с answered-> на answered.)

Когда вы вызываете эту функцию и хотите передать объект, управляемый unique_ptr<binaryBase> ptr, тогда передайте управляемый объект, а не сам unique_ptr с *ptr.

В тех случаях, когда вы действительно хотите передать владение указателем, вам нужно переместить указатель:

void func(std::unique_ptr<binaryBase>);

// ...
std::unique_ptr<binaryBase> ptr = /* ... */
func(std::move(ptr));

После вызова до func(), ptr больше не содержит объекта. func() вступил во владение им.

unique_ptr - это «только для перемещения» тип. Его нельзя скопировать, поскольку его конструктор копирования и оператор назначения копирования были удалены, что является причиной вашей исходной ошибки компиляции.

1 голос
/ 09 февраля 2020
char askQuestion(string *questions[8], unique_ptr<binaryBase>answered)

Вы пытаетесь передать std::unique_ptr по значению askQuestion(), но это тип только для перемещения . Он представляет собой динамически размещенный объект, который не используется несколькими объектами одновременно. Вы можете только переместить unique_ptr или передать его по ссылке. Если вы намереваетесь передать владение уникальным указателем, вам нужно использовать std::move:

askQuestion(questions, std::move(answered));

, где answered - это std::unique_ptr<binaryBase>. После того, как право собственности перешло к функции, вызывающая сторона не сможет снова использовать этот уникальный указатель.

Если вы не хотите передавать владение, тогда его можно передать по ссылке. Измените askQuestion(), чтобы сделать это:

 char askQuestion(string *questions[8], unique_ptr<binaryBase> &answered); //non-const lvalue reference

или

char askQuestion(string *questions[8], const unique_ptr<binaryBase> &answered);  //const lvalue reference

При передаче по ссылке функция может использовать указатель, но не владеть им, если вы явно не используете std::move в функция с уникальным указателем на неконстантную ссылку на значение (не может быть перемещена ссылка на постоянное значение).

bool checkAnswer(char answer, int place, binaryBase* reference)

В своем коде вы передаете указатель на binaryBase функции checkAnswer(). Опять же, для этой функции нет необходимости иметь уникальный указатель, поэтому вы можете передать уникальный указатель по ссылке, как показано выше, или использовать метод std::unique_ptr *1033*, чтобы получить указатель на объект.

Возможно, вы захотите проверить этот ответ , в котором рассматриваются различные способы всесторонней передачи уникального указателя.

...