请教一个C++的问题:函数返回为值和引用的区别。
template<classT>inlineTmin(constT&first,constT&second){returnfirst<second?first:secon...
template <class T>
inline T min(const T& first,const T& second)
{
return first < second ? first : second;
}
template <class T>
inline const T& min2(const T& first,const T& second)
{
return first < second ? first : second;
}
int main()
{
min(2,3); //ok
min("hello","nihao"); //error,?????????!!!!!!!!!!!!
//
min2(3,4);//ok
min2("hello","nihao"); //ok
} 展开
inline T min(const T& first,const T& second)
{
return first < second ? first : second;
}
template <class T>
inline const T& min2(const T& first,const T& second)
{
return first < second ? first : second;
}
int main()
{
min(2,3); //ok
min("hello","nihao"); //error,?????????!!!!!!!!!!!!
//
min2(3,4);//ok
min2("hello","nihao"); //ok
} 展开
4个回答
展开全部
通常来说, 返回引用更加的高效, 因为不需要额外的复制操作.
但是, 你无法返回局部对象的引用, 因为它们在函数结束之后将被销毁.
所以返回引用, 通常返回的是引用参数的值, 因为引用参数传递自函数外部, 不是局部的对象.
min("hello","nihao"); //error,?????????!!!!!!!!!!!!
-- 这里之所以有问题, 在于C++不允许直接返回数组.
-- 这个函数会被尝试实例化为:
-- char [6] min(char [6], char [6]);
-- 字面值字符串直接作为参数时直接被看成是数组
-- 但是如果先 char* p = "hello";
-- min(p, p2) 这样运行, 因为参数实例化为指针const char*.
不许返回数组很好理解, 前面也说了, 值返回需要复制一份, 但是数组不允许直接复制.
int a[10];
int b[10] = a; // 明显不行
min2之所以允许, 在于C++虽然不允许返回数组, 但是允许返回数组的引用.
C++标准规定
(1)引用、指针、数组、结构和对象等可以作为函数参数
(2)函数有:引用返回值、指针返回值、对象返回值
虽然很少直接会这么写, 返回数组引用的写法是这样.
int (&fun())[10]; // fun没有参数, 返回 int [10]的引用
但是, 你无法返回局部对象的引用, 因为它们在函数结束之后将被销毁.
所以返回引用, 通常返回的是引用参数的值, 因为引用参数传递自函数外部, 不是局部的对象.
min("hello","nihao"); //error,?????????!!!!!!!!!!!!
-- 这里之所以有问题, 在于C++不允许直接返回数组.
-- 这个函数会被尝试实例化为:
-- char [6] min(char [6], char [6]);
-- 字面值字符串直接作为参数时直接被看成是数组
-- 但是如果先 char* p = "hello";
-- min(p, p2) 这样运行, 因为参数实例化为指针const char*.
不许返回数组很好理解, 前面也说了, 值返回需要复制一份, 但是数组不允许直接复制.
int a[10];
int b[10] = a; // 明显不行
min2之所以允许, 在于C++虽然不允许返回数组, 但是允许返回数组的引用.
C++标准规定
(1)引用、指针、数组、结构和对象等可以作为函数参数
(2)函数有:引用返回值、指针返回值、对象返回值
虽然很少直接会这么写, 返回数组引用的写法是这样.
int (&fun())[10]; // fun没有参数, 返回 int [10]的引用
展开全部
首先你的代码有几处需要修改,修改后的代码附下:
#include<iostream>
using namespace std;
template <class T>
inline T min(const T first,const T second)
{
return first < second ? first : second;
}
template <class T>
inline const T& min2(const T first,const T second)
{
return first < second ? first : second;
}
int main()
{
cout<< min(2,3)<<endl; //ok
cout<<min("hello","nihao")<<endl; //error,?????????!!!!!!!!!!!!
cout<<min2(3,4)<<endl;//ok
cout<<min2("hello","nihao")<<endl; //ok
return 0;
}
然后解释你的问题
1.返回值与返回引用的区别:如果返回值的话,编译器是将你return 语句中的表达式的值赋给一个临时变量,我们就称之为temp。如果只返回值得话,我们不能连续执行函数的功能。可能这边讲的有点抽象,下面我举个例子。比如我在一个类中重载运算符“<<”;
下面我先使用返回值得方式重载,随后在用返回引用的方式重载
class Point
{
public:ostream operator<<(ostream & out);
private:
int x;
int y;
};
ostream Point::operator<<(ostream &out)
{
cout<<x<<","<<y<<endl;
}//返回值
class Point
{
public:ostream& operator<<(ostream & out);
private:
int x;
int y;
};
ostream& Point::operator<<(ostream &out)
{
cout<<x<<","<<y<<endl;
}//返回引用
这是来看一条语句
Point p,q;
cout<<p<<q<<endl;
如果采用返回值得话我们先执行cout<<p;返回一个ostream对象。继续执行下去就是out<<q;这个时候的out可能就不是刚才我们执行的流对象,也就意味着我们不能连续两次输出;
但是如果执行返回引用的话,我们就保证了两次输出时用的同一个流对象。除了这个例子外,你还可以试着用我刚才的方法分析一下++运算符;
2.你的代码中的问题首先是在c++中我们不能建立指针的引用;而你在使用min("hello","nihao");时,对于字符串你传的是首地址,这样其实就是建立指针的引用,这是不允许的。还有你在调用的时候其实T被实例化为char*,那么你在返回值得时候其实就是用你的const char*给char *赋值,赋值号两边类型不同时不能赋值的,并且这里即使是显式调用强制转化也不行。
#include<iostream>
using namespace std;
template <class T>
inline T min(const T first,const T second)
{
return first < second ? first : second;
}
template <class T>
inline const T& min2(const T first,const T second)
{
return first < second ? first : second;
}
int main()
{
cout<< min(2,3)<<endl; //ok
cout<<min("hello","nihao")<<endl; //error,?????????!!!!!!!!!!!!
cout<<min2(3,4)<<endl;//ok
cout<<min2("hello","nihao")<<endl; //ok
return 0;
}
然后解释你的问题
1.返回值与返回引用的区别:如果返回值的话,编译器是将你return 语句中的表达式的值赋给一个临时变量,我们就称之为temp。如果只返回值得话,我们不能连续执行函数的功能。可能这边讲的有点抽象,下面我举个例子。比如我在一个类中重载运算符“<<”;
下面我先使用返回值得方式重载,随后在用返回引用的方式重载
class Point
{
public:ostream operator<<(ostream & out);
private:
int x;
int y;
};
ostream Point::operator<<(ostream &out)
{
cout<<x<<","<<y<<endl;
}//返回值
class Point
{
public:ostream& operator<<(ostream & out);
private:
int x;
int y;
};
ostream& Point::operator<<(ostream &out)
{
cout<<x<<","<<y<<endl;
}//返回引用
这是来看一条语句
Point p,q;
cout<<p<<q<<endl;
如果采用返回值得话我们先执行cout<<p;返回一个ostream对象。继续执行下去就是out<<q;这个时候的out可能就不是刚才我们执行的流对象,也就意味着我们不能连续两次输出;
但是如果执行返回引用的话,我们就保证了两次输出时用的同一个流对象。除了这个例子外,你还可以试着用我刚才的方法分析一下++运算符;
2.你的代码中的问题首先是在c++中我们不能建立指针的引用;而你在使用min("hello","nihao");时,对于字符串你传的是首地址,这样其实就是建立指针的引用,这是不允许的。还有你在调用的时候其实T被实例化为char*,那么你在返回值得时候其实就是用你的const char*给char *赋值,赋值号两边类型不同时不能赋值的,并且这里即使是显式调用强制转化也不行。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
为值的话,有一个临时变量到返回值的拷贝,会对临时变量到函数返回值的赋给的那个对象有个拷贝,即先保存一个临时变量,再复制,当然了,优化的好的编译器会直接赋过去,这样就省了一次拷贝和析构了。;对象的话,会调拷贝赋值操作符;如果对象里有非基本类型的话,要重写=。
为引用的话,就是直接返回对所指的类型的实例的引用了。
不知这么说清楚了没
为引用的话,就是直接返回对所指的类型的实例的引用了。
不知这么说清楚了没
追问
呵呵,你这么讲,我不太清楚啊。
要不你帮我把代码出错地方的原因分析一下吧,或许能让我明白了,谢谢。
追答
看essential C++吧。作为入门很好的书。上面都有讲这些内容的。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
函数返回为引用主要是用在赋值语句“=”的左边,其他语句不能这么放置!参见c++面向对象程序设计 清华版
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询