2009-10-05 85 views
5

[EDIT 1 - 加入第三指针语法(感谢亚历克斯)]C++ DAL - 返回参考或填充传入参考

您喜欢哪方法,用于一DAL和为什么会出:

Car& DAL::loadCar(int id) {} 
bool DAL::loadCar(int id, Car& car) {} 
Car* DAL::loadCar(int id) {} 

如果无法找到汽车的第一个方法返回null,则第二个方法返回false。

第二种方法会在堆上创建一个Car对象,并填充从数据库查询的数据。据推测(我的C++是非常生锈),这将意味着沿行代码:

Car& DAL::loadCar(int id) 
{ 
    Car *carPtr = new Car(); 
    Car &car= *carPtr; 
    car.setModel(/* value from database */); 
    car.setEngineSize(/* value from database */); 
    // etc 
    return car; 
} 

由于

回答

5

第二绝对优选的。你正在返回一个对已经被new'd对象的引用。对于使用该软件的最终用户来说,返回的对象需要删除并不明显。 PLUS如果用户做了这样的事情

Car myCar = dal.loadCar(id); 

指针会丢失。

因此,您的第二种方法将控制内存放在调用者上,并停止发生任何奇怪的错误。

编辑:通过引用返回是明智的,但只有当父级(即DAL)类可以控制引用的生存期时。即如果DAL类有一个Car对象的向量,那么返回一个引用将是一个非常明智的事情。

编辑2:我还是喜欢第二个设置。第三个比第一个好得多,但你最终使得调用者假定对象被初始化。

你也可以提供

Car DAL::loadCar(int id); 

并希望接受的堆栈副本。

另外不要忘记,你可以创建一种空汽车对象,这样你就可以返回一个“有效”的ish对象,但是在所有的字段中没有返回任何有用的信息(因此显然被初始化为垃圾数据)。这是空对象模式。

+0

谢谢。即使调用者写了“Car&myCar = dal.loadCar(id)”,指针也不会丢失?无论如何,非DAL代码可以删除由DAL创建的内存吗? – ng5000 2009-10-05 13:37:00

+0

如果调用者写下你刚写入的内容“可以”已经释放,否则不需要。你需要调用“删除&myCar;”来做到这一点,虽然..这看起来很奇怪。 – Goz 2009-10-05 14:07:19

+0

栈拷贝甚至可能不会发生:根据编译器和优化,(N)RVO可能会启动并使操作等同于#1。无论如何,当汽车没有找到时抛出异常是必要的。 – 2009-10-05 14:45:48

4

由于您无论如何都在堆上分配对象,为什么不考虑Car * LoadCar(),如果发生问题,它将返回NULL。这样,您对引用类型没有限制(每个引用必须被初始化),并且还有手段来指示错误情况。

+0

听起来合理,更新的问题添加第三个选项。 – ng5000 2009-10-05 13:39:27

+0

Car&DAL :: loadCar(int id)不能返回NULL;没有空引用,只有空指针。 – Massa 2009-10-05 16:56:09