我知道这可能是以下内容的重复:Return a "NULL" object if search result not found
但是,我的代码有一些不同的地方,因为星号并没有解决我的问题,这是:
Normal Sphere::hit(Ray ray) {
//stuff is done here
if(something happens) {
return NULL;
}
//other stuff
return Normal(something, somethingElse);
}
但是我在引用return NULL
行时得到一个错误:conversion from ‘int’ to non-scalar type ‘Normal’ requested
另一个错误和警告是引用最后一个返回行:warning: taking address of temporary
和conversion from ‘Normal*’ to non-scalar type 'Normal' requested
我知道为什么我得到这个警告,但我不知道如何解决它。如何在函数结束后的最后一行返回一个Normal
对象,以及如何在第一次返回一个NULL
对象?(如果有一个术语来描述这些类型的回报,请让我知道,这样我也可以更多地阅读它。
为了澄清一个评论者的问题,我尝试了这些事情:
我试着这样做:cpp文件中的Normal *Sphere::hit(Ray ray)
和头文件中的Normal *hit( Ray ray );
,我得到这个错误:error: prototype for ‘Normal* Sphere::hit(Ray)’ does not match any in class 'Sphere'
我也试过这个:cpp文件中的Normal Sphere::*hit(Ray ray)
和头文件中的Normal *hit( Ray ray);
,我在第二个return语句中得到了这个错误:cannot convert 'Normal*' to 'Normal Sphere::*' in return
**进一步澄清:**我不是在问指针如何工作。(这不是主要的问题。)我想知道C中关于指针的语法。因此,给定我上面指定的函数,我发现我应该指定一个返回指针,因为C没有空对象。明白了。但是,问题就变成了:函数原型应该是什么样的?在cpp文件中,我有巴拉的建议(这是我最初的建议,但由于以下错误而更改了它):
Normal* Sphere::hit(Ray ray) {
//stuff is done here
if(something happens) {
return NULL;
}
//other stuff
return new Normal(something, somethingElse);
}
在头文件中,我有Normal *hit(Ray ray)
,但我仍然得到以下消息:prototype for 'Normal* Sphere::hit(Ray)' does not match any in class 'Sphere'
在这一点上,我不清楚为什么它找不到该函数原型。下面是头文件:
class Sphere
{
public:
Sphere();
Vector3 center;
float radius;
Normal* hit(Ray ray);
};
有谁能明白为什么它在抱怨Sphere
类中不存在hit
的匹配原型吗?(我可能会把这个问题转移到另一个问题上……)
8条答案
按热度按时间igsr9ssn1#
我觉得你需要像
可以返回NULL;
hsgswve42#
有几种相当标准的方法可以做到这一点。这些方法有不同的权衡,我不打算在这里讨论。
方法1:在失败时抛出异常。
方法2返回指向新分配对象指针。(你也可以使用智能指针,或者auto_ptrs来使它更整洁)。
方法3是更新现有对象。(你可以传递一个引用,但我使用的一个约定是任何输出参数都是通过指针传递的)。
方法4:返回
optional<Normal>
(使用boost或类似方法)bq8i3lrv3#
如果使用Boost库,则可以使用boost::optional。这给了你一个非常接近null的值:
boost::optional< T>是一个 Package 类,它包含T的示例或boost::none(boost::none_t的示例)。
请参阅http://www.boost.org/doc/libs/1_47_0/libs/optional/doc/html/index.html了解更多详细信息。
avwztpqn4#
在C中,没有“空对象”这样的东西。但是有null指针。你可以实现一个特殊的对象,你的设计,你逻辑上视为“空”,但它不是 C 的一部分。
pkwftd7m5#
NULL返回值只有在返回一个指向Normal对象的指针时才有效,NULL表示空指针,而不是空对象。
在这种情况下,我将为该对象定义一个“null”或无效状态。由于您正在使用曲面法线,因此可以将长度为== 0的法线视为无效状态,因此可以执行以下操作:
然后你的普通类会有这样的东西:
f5emj3cl6#
但是,我的代码有一些不同的地方,因为星号并没有解决我的问题,这是:
从您的问题来看,您似乎希望在类名后添加一个
*
就可以解决您的问题。然而,这种期望来自于缺乏对指针是什么、何时使用指针以及类型系统的重要性的理解。因此,本答案的其余部分有望澄清这些观点。首先,C++是一种强类型语言。这意味着当将一个变量赋值给另一个变量时,这两个变量必须是相同的类型。例如,假设在下面的代码中,A和B是没有定义成员的基本类:
这是因为
a
和b
是不同的类型。现在假设您使用
*
创建了一个指针。这也是一个不同类型的变量:p_a
与a
不是同一类型的变量。现在错误:
请求从“int”到非标量类型“Normal”的转换
因为表达式:
类型为
int
(如果你查找它,你会发现它的#定义为0),但你的函数的返回类型是Normal
。要解决这个问题,必须将函数返回类型更改为
pointer to a Normal
对象。返回一个
pointer to a Normal
对象:然而,在这个阶段,虽然编译器错误应该被解决,但是您现在需要考虑管理动态分配的内存。我不能在这篇文章中涵盖这一点,所以我会让它保持原样。
更新:
这是回答你问题的第二部分。头文件中的类声明应以
;
结尾。jvlzgdj97#
你不应该返回
NULL
,这是一个int
类型的零常量,而是返回一个由no arg构造函数构造的类Normal
的空示例。因此返回
Normal();
通常,最好另外定义方法
isEmpty()
。这样你就可以像这样检查一个
Null
示例:nhn9ugyo8#
我曾经面对过这种问题。如果你想,对于非限定条件,你可以只返回
normal
对象,其中有你想要的最小值/默认值,比如:因为你的函数的返回类型是
Normal
,所以你可以只传递一个Normal
类型的对象,它的值最小,比如例如0或其他值,然后你可以在函数的堆栈终止时进一步处理。希望这能解决你的问题。