C++ C++;DAL-返回引用或填充传入引用

C++ C++;DAL-返回引用或填充传入引用,c++,reference,pass-by-reference,interface-design,C++,Reference,Pass By Reference,Interface Design,[编辑1-添加了第三个指针语法(谢谢Alex)] 对于DAL,您更喜欢哪种方法?为什么: Car& DAL::loadCar(int id) {} bool DAL::loadCar(int id, Car& car) {} Car* DAL::loadCar(int id) {} 如果找不到car,第一个方法返回null,第二个方法返回false 第二种方法将在堆上创建一个Car对象,并使用从数据库查询的数据进行填充。大概(我的C++非常生疏),这意味着代码: Car&

[编辑1-添加了第三个指针语法(谢谢Alex)]

对于DAL,您更喜欢哪种方法?为什么:

Car& DAL::loadCar(int id) {}
bool DAL::loadCar(int id, Car& car) {}
Car* DAL::loadCar(int id) {}
如果找不到car,第一个方法返回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;
}

谢谢

第二个肯定更好。您正在返回对新对象的引用。对于使用软件的最终用户,返回的对象是否需要删除并不明显。另外,如果用户做了这样的事情

Car myCar = dal.loadCar( id );
指针会丢失

因此,您的第二种方法将内存控制权交给调用方,并阻止任何奇怪的错误发生

编辑:通过引用返回是合理的,但仅当父类(即DAL)对引用的生存期具有控制权时。也就是说,如果DAL类中有一个Car对象的向量,那么返回一个引用将是一件非常明智的事情

我还是喜欢第二套。第三个远比第一个好,但最终会使调用方假定对象已初始化

你也可以提供

Car DAL::loadCar(int id);
并希望接受堆栈副本


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

因为你在堆上分配对象,为什么不考虑CAR*Load Car(),如果出现问题,它返回null。通过这种方式,您对引用类型没有任何限制(每个引用都必须初始化),并且还可以发出错误情况的信号

谢谢。即使调用方写下“Car&myCar=dal.loadCar(id)”指针也不会丢失吗?非DAL代码是否可以删除DAL创建的内存?如果调用方写入了您刚刚写入的内容,则内存“可能”可用。但是,您需要调用“delete&myCar;”来执行此操作。。这看起来很奇怪。堆栈复制甚至可能不会发生:取决于编译器和优化,(N)RVO可能会启动并使操作等效于#1。在任何情况下,在找不到汽车时抛出异常都是必要的。Null对象模式不需要异常。Car&DAL::loadCar(int-id)不能返回Null;没有空引用,只有空指针。