怎样解决not all control paths return a value警告?(6行程序,VC++6)

fiveyes 2003-04-10 11:28:40
怎样解决not all control paths return a value警告?(VC++6)

例如,这样一个函数:

//重载的(),访问行x,列y的元素
int &DoubleSubscriptArray::operator()( int x, int y )
{
if( x >= 0 && x <= row && y >= 0 && y <= column )
return data[ x ][ y ];
else //编译器发现这条路径不会返回值
cout << "错误!没有此元素!" << endl;
}

编译器会对它警告,说在这个函数里,并非所有路径都能返回一个值。可是,当输入的数据有问题的时候(x或者y的值是非法的),我应该返回什么呢?正常的数据可以是任何整数,那我该返回什么东东,才能表示失败的函数调用呢?

或者,不理会编译器的警告,会有什么问题吗?

还是应该更改一下程序的结构呢?
...全文
5558 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
fixopen 2003-04-11
  • 打赏
  • 举报
回复
版本一
int& DoubleSubscriptArray::operator()(int x, int y)
{
assert(x >= 0 && x <= row && y >= 0 && y <= column);
return data[x][y];
}

版本二
int& DoubleSubscriptArray::operator()(int x, int y)
{
if(x <= 0 || x >= row || y <= 0 || y >= column)
throw new range_of_over("x and y is invalid value");
return data[x][y];
}

我推荐版本一,因为X, Y越界是调用者的事,好好看看Design by Contract就会觉得很有道理的。
fiveyes 2003-04-11
  • 打赏
  • 举报
回复
谢谢大家!
最后我得出两个结论:
1、这个问题很适合使用异常处理机制。
2、我该结帖了。^_^
zhouzhaohan 2003-04-10
  • 打赏
  • 举报
回复
那是你程序逻辑的问题,函数设计的问题。
你怎么使用那个函数的?
LoveCreatesBeauty 2003-04-10
  • 打赏
  • 举报
回复
返回出错值,调用时判断()的返回值,并相应处理。
fiveyes 2003-04-10
  • 打赏
  • 举报
回复
exit倒也干净,可是为了这么个错误就把程序Kill掉,未免有些过分?

在调用函数前先过滤数据,保证传递给函数的数据是合法的,也是个办法,可是,这样一来,函数就不方便使用了,似乎也不完整了(不带错误处理的函数?)。

忽略的话,又不知道当这样的时候会发生什么事?

假设已经声明了一个对象A,10行10列:

int value = a( 11, 12 );

说不定它还会被当作左值:

a( 11, 12 ) = 200;

困惑ing
yatuor 2003-04-10
  • 打赏
  • 举报
回复
此warning可以忽略,ok?
winespirit 2003-04-10
  • 打赏
  • 举报
回复
不要返回常数的引用!
allen_zhaozhencn 2003-04-10
  • 打赏
  • 举报
回复
我认为你的函数如果返回引用的话,最好把if条件判定放在函数体外;
woxihuanbohe 2003-04-10
  • 打赏
  • 举报
回复
int &DoubleSubscriptArray::operator()( int x, int y )
{
if( x >= 0 && x <= row && y >= 0 && y <= column )
return data[ x ][ y ];
else //编译器发现这条路径不会返回值
{
cout << "错误!没有此元素!" << endl;
exit(0);
}
}
这个函数返回的是引用啊,return 0 ;怎么会对呢 !?
firela 2003-04-10
  • 打赏
  • 举报
回复
错了,我试了一下return 0;不行。

为什么要返回引用呢,返回指针不是更好?
huigll 2003-04-10
  • 打赏
  • 举报
回复
我想直接终止算了。
exit(0);
firela 2003-04-10
  • 打赏
  • 举报
回复
最后加上return 0;
fiveyes 2003-04-10
  • 打赏
  • 举报
回复
我把“异常处理”那一章快速看了一遍,凑合着把这个程序改写成抛出&处理异常方式的:(其它地方没动,所以我省略了。)

不合理的和错误的地方,还请指出来啊!谢!

//重载的(),访问行x,列y的元素
int & DoubleSubscriptArray::operator()( int x, int y )
{
if( x >= 0 && x < row && y >= 0 && y < column )
return data[ x ][ y ];
else
throw(""); //抛出异常
}

//重载的(),访问行x,列y的元素
const int & DoubleSubscriptArray::operator()( int x, int y ) const
{
if( x >= 0 && x < row && y >= 0 && y < column )
return data[ x ][ y ];
else
throw(""); //抛出异常
}

int main() //VC++6的运行结果
{
DoubleSubscriptArray a( 3, 5 ); //ok
cout << a; //ok,三行五列的0

a( 2, 2 ) = 10; //ok
cout << a( 2, 2 ) << endl; //ok,一个10

try {
cout << a( 3, 4 ) << endl;
}
catch( ... ) {
cout << "错误!" << endl; //输出"错误!"
}

try {
int x = a( 3, 4 );
cout << x << endl; //没有执行这句
}
catch( ... ) {
cout << "错误!" << endl; //输出"错误!"
}
try {
a( 3, 4 ) = 10;
cout << a( 3, 4 ); //没有执行这句
}
catch( ... ) {
cout << "错误!" << endl; //输出"错误!"
}

return 0;
}

呵呵,看来异常处理有时候还是挺有用的。在这个程序里,不方便在函数外面作错误处理,里面作错误处理吧,又找不到合适的返回值,又不想就这么把程序就exit了(assert也是一样),这时候异常处理就派上用场了。
fiveyes 2003-04-10
  • 打赏
  • 举报
回复
忽然想起一件事来,这是一个重载的()运算符,怎么在函数外面进行错误处理呢?

唉,难怪《C++大学教程》里面有那么大一堆assert,看来有时候错误处理这东西是挺难搞。

我看一下异常处理吧,还没学到这儿呢。*^_^*

哪位有什么高招可以解决此问题的,一定要不吝赐教啊!
_goolooloo_ 2003-04-10
  • 打赏
  • 举报
回复
对于声明为有返回值的函数,如果程序中没有显示的返回一个值(使用return),程序将返回一个随机值,使用这个值是危险的。

抛出异常会怎样?
sandrowjw 2003-04-10
  • 打赏
  • 举报
回复
throw Invalid_Input();
fiveyes 2003-04-10
  • 打赏
  • 举报
回复
这是《C++大学教程》里面的一道习题:

//生成DoubleSubscriptArray类,与图8.4的Array类的特性相似。构造时,类应生成任意
//行数和列数的数组。类用operator()进行双下标操作。例如,在3×5的DoubleSubscriptArray
//数组a中,用户可以用a(1, 3)访问行1列3的元素。记住,operator()可以接收任何参数(关
//于operator)的例子,见图8.5的String类)。双下标数组的基本表达方式为rows*columns个
//元素的单下标数组。函数operator()应通过正确的指针算法访问数组的每个元素。实际上,
//operator()应有两个版本,一个返回int &,使DoubleSubscriptArray的元素可以用作左值,
//一个返回const int &,使const DoubleSubscriptArray的元素可以用作右值。这个类还应提
//供下列运算符:==、!=、=、<<(以行和列格式输出数组)和>>(输入整个数组内容)。

我目前的程序是这样的:(运行结果出现奇怪的整数和非法操作,说明这个警告是没办法忽略的)

#include <iostream.h>

class DoubleSubscriptArray { //双下标数组类
friend ostream &operator<<( ostream &, const DoubleSubscriptArray & ); //重载<<运算符
public:
DoubleSubscriptArray( int, int ); //构造函数
~DoubleSubscriptArray(); //析构函数
int &operator()( int x, int y ); //重载的(),访问行x,列y的元素
const int &operator()( int x, int y ) const; //重载的(),访问行x,列y的元素
private:
int **data; //到指针的指针,以便在运行时决定二维数组的大小
int row; //用来记录行数
int column; //用来记录列数
};

//构造函数
DoubleSubscriptArray::DoubleSubscriptArray( int x, int y )
{
data = new int* [ x ]; //产生各个行

for( int i = 0; i < x; i++ )
data[ i ] = new int[ y ]; //产生各个列

for( i = 0; i < x; i++ ) //初始化所有元素为0
for( int j = 0; j < y; j++ )
data[ i ][ j ] = 0;

row = x; //记录行数
column = y; //记录列数
}

//析构函数
DoubleSubscriptArray::~DoubleSubscriptArray()
{
for( int i = 0; i < row; i++ )
delete [] data[ i ]; //删除各个列

delete [] data; //删除各个行
}

//重载的(),访问行x,列y的元素
int & DoubleSubscriptArray::operator()( int x, int y )
{
if( x >= 0 && x < row && y >= 0 && y < column )
return data[ x ][ y ];
else
cout << "错误!没有此元素!" << endl;
}

//重载的(),访问行x,列y的元素
const int & DoubleSubscriptArray::operator()( int x, int y ) const
{
if( x >= 0 && x < row && y >= 0 && y < column )
return data[ x ][ y ];
else
cout << "错误!没有此元素!" << endl;
}

//重载<<运算符
ostream &operator<<( ostream &output, const DoubleSubscriptArray &a )
{
for( int i = 0; i < a.row; i++ ) {
for( int j = 0; j < a.column; j++ )
cout << a.data[ i ][ j ] << " ";
cout << endl;
}
return output;
}

int main() //VC++6的运行结果
{
DoubleSubscriptArray a( 3, 5 ); //ok
cout << a; //ok,三行五列的0

a( 2, 2 ) = 10; //ok
cout << a( 2, 2 ) << endl; //ok,一个10

cout << a( 3, 4 ) << endl; //"错误!没有此元素!",然后是"43500012"?
int x = a( 3, 4 ); //"错误!没有此元素!",ok,可是……
cout << x << endl; //又是"4350012"?
a( 3, 4 ) = 10; //"错误!没有此元素!",然后就“非法操作”。

return 0;
}

这样看来,可行的办法就是exit和在函数外面进行数据验证了?

也许最好的办法就是在函数外面事先对数据进行验证?

69,378

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧