C++ 指针引用的问题
无法编译的原因:C++ 指针引用的问题,c++,reference,C++,Reference,无法编译的原因: // RefToPointers.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> using std::cout; class T { public: T(int* value):data_(value) { } int* data_; int* getData_()
// RefToPointers.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using std::cout;
class T
{
public:
T(int* value):data_(value)
{
}
int* data_;
int* getData_()
{
return data_;
}
int getValue()//<----------Here I do not return by ref
{
return *data_;
}
};
void fnc(const int*& left, const int*& right )//<------Doesn't work even though
//it is identical to the example below just type is different. Why?
{
const int* tmp = left;
left = right;
right = tmp;
}
void fnc(const int& left,const int& right)//<---Here I pass by ref
{
}
int _tmain(int argc, _TCHAR* argv[])
{
//int* one = new int(1);
//int* two = new int(2);
//cout << "Pointers before change:" << *one << '\t' << *two << '\n';
//fnc(one,two);
//cout << "Pointers before change:" << *one << '\t' << *two << '\n';
T one(new int(1));
T two(new int(2));
fnc(one.getData_(),two.getData_());//<---This do not work
fnc(one.getValue(),two.getValue());//<<------This still works even thoug I'm
//returning by value and fnc is taking args by ref. Why does it work with int
//by not with int*?
return 0;
}
//RefToPointers.cpp:定义控制台应用程序的入口点。
//
#包括“stdafx.h”
#包括
使用std::cout;
T类
{
公众:
T(int*value):数据(value)
{
}
int*数据;
int*getData_u389;()
{
返回数据;
}
int getValue()//
此函数返回一个r值,但int*&
需要一个l值,因此编译器会抱怨。您还应该在getData()中返回一个int*&
int*& getData_() { return data_; }
同时,const int&
可以接受右值,因此第二个fnc
可以正确编译。const
引用与(可变)引用并不完全相同
(当然,最好也提供const版本
int* const& getData_() const { return data_; }
// or: int* getData_() const { return data_; }
还要注意的是,当你新建而不删除-ing它时,你的程序会泄漏内存。你只能在变量上引用(&),而不能在函数的返回值上引用(&),当你更改它时,更改会发生在哪里?因为getData()返回int*而不是int*&。这意味着您将临时变量作为实际参数传递给fnc,并且临时变量不能转换为(可变)引用。请将getData_u()更改为返回int*&。注意
按值返回指针。这意味着临时指针用于保存调用返回的指针。您不能创建(非常量)对临时指针的引用(如果您在T
类中交换内部指针的两个临时副本会有什么意义?)
(至于你的第二个问题,我认为当其他格式修饰符(如*)出现在你的行中时,斜体将被取消…getData()
返回右值。你不能引用右值指针
你有两个选择:
1) 传递fnc()
左值:
int* lhs = one.getData_();
int* rhs = two.getData_();
fnc(lhs, rhs);
2) 或者,既然您正在传递指针引用,而指针引用实际上与指针本身大小相同,为什么不只传递指针呢
void fnc(int* left, int* right )
{
int* tmp = left;
left = right;
right = tmp;
}
编辑:
关于左值和右值的更多信息。“左值”用于表示“可以位于=
操作左侧的表达式”。右值实际上是相反的:右值是任何不能位于=
操作左侧的表达式
现在事情比这复杂了一点,但这仍然是理解左值和右值的一个很好的方法
现在,考虑下面的代码:
int val()
{
return 42;
}
int main()
{
int* p = &val();
}
val()
按值返回一个int
——换句话说,它返回一个未命名的临时值。您应该能够获取该临时值的地址吗
你可能会想,“嗯,是的,为什么不呢?”但答案实际上是否定的,你不能获取临时文件的地址。原因与临时文件的生命周期有关。它的范围仅限于创建它的表达式。换句话说:val()
。只要val()
已被完全评估,临时文件不再存在。实际上,它从堆栈中脱落。当int*p=&
被评估时,临时文件早已不存在了。没有任何东西可以获取其地址
这就是你不能获取右值地址的基本原因,也就是你不能获取右值地址的引用的原因。你想要什么是常量?指针,还是它指向的东西?没关系,我想一个elf过来并键入了const
好的,你的编辑现在使所有答案无效…相关帖子:@KennyTM thanks有效,但也确实让我的头脑有点乱。我认为返回指针的许多原因之一是确保不复制tmp。例如,如果我有另一个fnc(看我编辑的问题)我不必指定为返回类型ref to int,它仍然有效,但在我返回指针时它不起作用,为什么?请您向我解释一下好吗?@那里:因为这是一个常量int&
,而不是int&
。常量引用可以接受右值。另外,您正在fn中交换指针值本身c
,而不是指针指向的内容。因此,作为指针的类型不会改变这种情况。@KennyTM它对指针不起作用(const ref到rvalue)。我已将getData()的返回类型更改为int*,将fnc中的参数更改为const int*&它不起作用,并且它与使用int的示例相同(常数到右值)。为什么?@那里:const int*&
表示对int的常量指针的可变引用。const int*&=int const*&
。你需要int*const&
这意味着对int的可变指针的常量引用。@KennyTM它现在可以工作了,但是……嗯……我不同意你的阅读方式,因为我会把这个常量int*&当作ref t来阅读o指向int的指针是const,而这个int*const&as ref to const pointer to int而不是const ref to mutable pointer of int,因为这个指针实际上是const not mutable,refs在默认情况下是const。我希望你同意我的观点。John,2)part什么也没做。它正在交换指向fnc
的指针的本地副本,这些指针在fnc
结束时会被忘记。感谢您的回答。首先,我回答您的问题:我不传递指针,因为我希望这些指针指向fnc主体内指向的值。如果我不通过ref thi传递它,那么现在,当我回答你的问题时,这里是我的问题:fnc(one.getData(),…)之间的区别在哪里你们展示的是什么?你们展示的是在堆栈上创建的变量,这就是为什么它们是左值吗?这对我来说没有意义,你们可能同意我的观点,为了将int(只是int)发送给函数,首先创建变量int left=getValue();然后将它(左变量)传递给函数fnc(INTA)?你通常会做什么
int val()
{
return 42;
}
int main()
{
int* p = &val();
}