C++中函数定义返回类型和内部实现返回类型不同的原因

这两天在看OSG的插件实现的源代码的过程中发现了一个让我比较纳闷的问题:比如在OBJ插件中,其实现的ReadWriterOBJ类的readNode函数,代码如下:


osgDB::ReaderWriter::ReadResult ReaderWriterOBJ::readNode(std::istream& fin, const Options* options) const
{
    if (fin)
    {
        fin.imbue(std::locale::classic());

        obj::Model model;
        model.readOBJ(fin, options);

        ObjOptionsStruct localOptions = parseOptions(options);

        osg::Node* node = convertModelToSceneGraph(model, localOptions, options);
        return node;
    }

    return ReadResult::FILE_NOT_HANDLED;
}

这个地方出现了一个现象:函数定义的返回类型和函数实际的返回类型不一致----这里函数定义的返回类型为osgDB::ReaderWriter::ReadResult,但是在实现中的实际返回类型却为Node*或者ReadResult中的一个枚举类型。

当时我看到这里就比较纳闷,ReadResult、Node、以及ReadResult内部的那个枚举类型之间没有共同的父类,如何做到类型的统一的呢?上了OSG群问了下,也是没有得到认真的回答,于是只有自己再认真看了看ReadResult的实现。

后来发现ReadResult实现了两个构造函数:

ReadResult(ReadStatus status=FILE_NOT_HANDLED):_status(status) {}
ReadResult(osg::Object* obj, ReadStatus status=FILE_LOADED):_status(status),_object(obj) {}

当时就猜想应该和它们有关,最后通过自己的测试代码和相关的资料的求证,的确是它们搞的鬼。(没系统学过编程果然细节上认识是不足的啊)

“在<<C++primer>>里有提到这个过程,函数返回对象首先会创建一个临时的类对象,该对象是由复制构造函数生成,参数是返回值。然后再调用复制构造函数初始化需要返回的新的对象

简单讲,就是现在函数需要返回类型A,A有通过类型B和C来构造对象的构造函数,那么在函数返回A时,如果实现中的返回类型为B和C,那么该函数则内部调用A的这两个构造函数来实现A的构造,并返回给函数调用处。我们可以通过如下测试代码更清晰的看到本问题的情况。

<pre name="code" class="cpp">class testClass
{
private:
	string testClassForm;
public:
	testClass(string name):testClassForm("string"){cout<<"constructed from string"<<endl;}//采用string构造
	testClass(int name):testClassForm("int"){cout<<"constructed from int"<<endl;}//采用int构造
	void logInfo(){cout<<"class form is "<<testClassForm<<endl;}
};

testClass testFunc(int type)
{
	switch(type)
	{
	case 0://用string来构造
		{
			string testStr="";
			return testStr;//代码上返回string
		}
	case 1://用int来构造
		{
			int testInt=0;
			return testInt;//代码上返回int
		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	testClass classFromString=testFunc(0);
	classFromString.logInfo();
	
	testClass classFromInt=testFunc(1);
	classFromInt.logInfo();

	return 0;
}
 

输出为:

constructed from string

class form is string

constructed from int

class form is int

请按任意键继续. . .

从这里可清楚的看到,在代码层返回的类型与实际返回数据类型在return时的内部细节是构造函数的调用来统一的,但是很显然如果被返回的类有空参数值的构造函数,那么在testFunc函数中直接return是会报错的。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值