может make_unique может хранить литералы или входные данные iostream - PullRequest
0 голосов
/ 10 мая 2018

когда я использовал обычный указатель типа char для хранения ввода от <iostream> до cin>>ptr, он был преобразован в массив (я понял, что, поскольку cout<<ptr; дает сохраненную строку и не дает адрес. И адрес дается cout<<&pointer;). но когда я использовал make_unique, это дало ошибки. почему они ведут себя одинаково. Пожалуйста, объясните это и как правильно хранить строковый ввод как массив символов, используя make_unique. Я приложил использованный код.

#include<iostream>
#include<string>
#include<memory>
using namespace std;
int main(){


//using of std::string
string str;
cout<<"Enter a str: ";
cin>>str;cout<<endl;
cout<<str<<"\n";


// using of ordinary pointer
char* str2;//as if u r assigning array to a pointer
cout<<"Enter a str: ";
cin>> str2;cout<<endl;
cout<<str2;
cout<<endl;

//using of arrays
char c[] = "ghfgtgbbb";
cout<<c;
char* cPtr = c;
cout<<"\n"<<cPtr;
cout<<endl;


//using of mak_unique (gives errors)
auto str3Ptr = make_unique<char>();
cout<<"Enter a str: ";
cin>> str3Ptr;cout<<endl;
cout<<str3Ptr;
cout<<endl;


return 0;}

1 Ответ

0 голосов
/ 10 мая 2018

Сначала,

// using of ordinary pointer
char* str2;//as if u r assigning array to a pointer
cout<<"Enter a str: ";
cin>> str2;cout<<endl;
cout<<str2;
cout<<endl;

может "работать", но на самом деле это неопределенное поведение. char* str2; создает указатель, который указывает на что-то, но мы понятия не имеем, что. Попытка сохранить в нем данные с помощью cin>> str2 является неопределенным поведением, поскольку у вас нет разрешения на запись того, на что указывает str2. Так что этого блока кода следует избегать.

Теперь давайте посмотрим на

//using of arrays
char c[] = "ghfgtgbbb";
cout<<c;
char* cPtr = c;
cout<<"\n"<<cPtr;
cout<<endl;

Это лучше, c - это массив из 10 символов, и cPtr инициализируется, чтобы указывать на него, чтобы он был действительным указателем. Вы не делаете ввод с ним, но вы можете, но вы должны убедиться, что вводите не более 9 символов (вы должны оставить место для нулевого терминатора).

Теперь рассмотрим код unique_ptr. В

//using of mak_unique (gives errors)
auto str3Ptr = make_unique<char>();
cout<<"Enter a str: ";
cin>> str3Ptr;cout<<endl;
cout<<str3Ptr;
cout<<endl;

Вы, по сути, сделали то же самое, что и первый блок кода. auto str3Ptr = make_unique<char>(); Создает уникальный указатель, указывающий на один char. По крайней мере, у вас есть инициализированная переменная, но она не будет достаточно большой для хранения ввода. Вам нужно будет использовать версию массива и выделить достаточно места для ввода, который вы хотите. Это будет выглядеть как

auto str3Ptr = make_unique<char[]>(80);
                                   ^^ number of elements to allocate

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

Итак, это оставляет нас с

//using of std::string
string str;
cout<<"Enter a str: ";
cin>>str;cout<<endl;
cout<<str<<"\n";

Какой правильный способ работы со строками в C ++. Он обрабатывает распределение и освобождение и предназначен для работы со стандартными потоками.

...