C ++에서 포인터에 대한 참조 전달
내가 알 수있는 한 C ++에서 포인터에 대한 참조를 전달해서는 안되는 이유가 없습니다. 그러나 그렇게하려는 시도가 실패하고 이유를 모릅니다.
이것이 내가하고있는 일입니다.
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
그리고 나는이 오류가 발생합니다 :
'std :: string *'에서 'std :: string * &'로 매개 변수 1을 변환 할 수 없습니다.
함수는 익명 문자열 포인터가 아닌 호출 범위의 실제 문자열 포인터에 대한 참조를 기대합니다. 그러므로:
string s;
string* _s = &s;
myfunc(_s);
잘 컴파일해야합니다.
그러나 이것은 함수에 전달하는 포인터를 수정하려는 경우에만 유용합니다. 문자열 자체를 수정하려면 Sake가 제안한대로 문자열에 대한 참조를 사용해야합니다. 이를 염두에두고 컴파일러가 원래 코드에 대해 불평하는 이유가 더 분명해야합니다. 코드에서 포인터는 '즉석에서'만들어 지므로 포인터를 수정해도 아무런 결과가 없으며 의도 한 것이 아닙니다. 참조 (포인터 대)의 아이디어는 참조가 항상 실제 객체를 가리키는 것입니다.
문제는 참조에 임시가 아닌 참조에 바인딩하려고하는데 C ++에서 참조가 아닌 경우 허용하지 않습니다 const
.
따라서 다음 중 하나를 수행 할 수 있습니다.
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
void myfunc2(string* const& val)
{
// Do stuff to the string pointer
}
int main()
// sometime later
{
// ...
string s;
string* ps = &s;
myfunc( ps); // OK because ps is not a temporary
myfunc2( &s); // OK because the parameter is a const&
// ...
return 0;
}
다음으로 변경하십시오.
std::string s;
std::string* pS = &s;
myfunc(pS);
편집하다:
This is called ref-to-pointer
and you cannot pass temporary address as a reference to function. ( unless it is const reference
).
Though, I have shown std::string* pS = &s;
(pointer to a local variable), its typical usage would be : when you want the callee to change the pointer itself, not the object to which it points. For example, a function that allocates memory and assigns the address of the memory block it allocated to its argument must take a reference to a pointer, or a pointer to pointer:
void myfunc(string*& val)
{
//val is valid even after function call
val = new std::string("Test");
}
&s
produces temporary pointer to string and you can't make reference to temporary object.
Try:
void myfunc(string& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(s);
// ...
}
or
void myfunc(string* val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
EDIT: I experimented some, and discovered thing are a bit subtler than I thought. Here's what I now think is an accurate answer.
&s
is not an lvalue so you cannot create a reference to it unless the type of the reference is reference to const
. So for example, you cannot do
string * &r = &s;
but you can do
string * const &r = &s;
If you put a similar declaration in the function header, it will work.
void myfunc(string * const &a) { ... }
There is another issue, namely, temporaries. The rule is that you can get a reference to a temporary only if it is const
. So in this case one might argue that &s is a temporary, and so must be declared const
in the function prototype. From a practical point of view it makes no difference in this case. (It's either an rvalue or a temporary. Either way, the same rule applies.) However, strictly speaking, I think it is not a temporary but an rvalue. I wonder if there is a way to distinguish between the two. (Perhaps it is simply defined that all temporaries are rvalues, and all non-lvalues are temporaries. I'm not an expert on the standard.)
That being said, your problem is probably at a higher level. Why do you want a reference to the address of s
? If you want a reference to a pointer to s
, you need to define a pointer as in
string *p = &s;
myfunc(p);
If you want a reference to s
or a pointer to s
, do the straightforward thing.
I have just made use of a reference to a pointer to make all the pointers in a deleted binary tree except the root safe. To make the pointer safe we just have to set it to 0. I could not make the function that deletes the tree (keeping only the root) to accept a ref to a pointer since I am using the root (this pointer) as the first input to traverse left and right.
void BinTree::safe_tree(BinTree * &vertex ) {
if ( vertex!=0 ) { // base case
safe_tree(vertex->left); // left subtree.
safe_tree(vertex->right); // right subtree.
// delete vertex; // using this delete causes an error, since they were deleted on the fly using inorder_LVR. If inorder_LVR does not perform delete to the nodes, then, use delete vertex;
vertex=0; // making a safe pointer
}
} // end in
Bottom line, a reference to a pointer is invalid when the formal parameter is the (this) pointer.
Welcome to C++11 and rvalue references:
#include <cassert>
#include <string>
using std::string;
void myfunc(string*&& val)
{
assert(&val);
assert(val);
assert(val->c_str());
// Do stuff to the string pointer
}
// sometime later
int main () {
// ...
string s;
myfunc(&s);
// ...
}
Now you have access to the value of the pointer (referred to by val
), which is the address of the string.
You can modify the pointer, and no one will care. That is one aspect of what an rvalue is in the first place.
Be careful: The value of the pointer is only valid until myfunc()
returns. At last, its a temporary.
I know that it's posible to pass references of pointers, I did it last week, but I can't remember what the syntax was, as your code looks correct to my brain right now. However another option is to use pointers of pointers:
Myfunc(String** s)
myfunc("string*& val") this itself doesn't make any sense. "string*& val" implies "string val",* and & cancels each other. Finally one can not pas string variable to a function("string val"). Only basic data types can be passed to a function, for other data types need to pass as pointer or reference. You can have either string& val or string* val to a function.
참고URL : https://stackoverflow.com/questions/823426/passing-references-to-pointers-in-c
'Programing' 카테고리의 다른 글
C ++에서 숫자를 문자열로 변환하거나 그 반대로 변환하는 방법 (0) | 2020.07.14 |
---|---|
기존 정보를 보존하면서 다른 유형과 메시지로 예외를 다시 발생시킵니다. (0) | 2020.07.14 |
Phonegap Cordova 설치 창 (0) | 2020.07.14 |
구조체가 상속을 지원하지 않는 이유는 무엇입니까? (0) | 2020.07.14 |
.NET에서 특정 앱의 여러 인스턴스를 방지합니까? (0) | 2020.07.14 |