是否可以从返回参数初始化变量(通过ref)?说我有类似的东西:
Car c; // <- don't want to create a new Car here!
if (findCar("beetle", c)) {
...
}
如果findCar
成功,则返回true并填充c
:
bool findCar(string name, Car& out) {
...
// return true if found
out = thecar;
return true;
}
现在,我的类Car没有0参数构造函数,因此上面的代码无法编译。有没有办法在调用c
之前保持findCar
未初始化?
我想到的解决方案是:
答案 0 :(得分:4)
排序。问题是引用绝对必须引用实际对象。因此,如果您通过引用返回,则必须为返回的引用创建一个对象。因此,如果找不到匹配的对象,则返回引用并不重要。如果传入引用,则必须首先创建一个对象,以便引用参数。
您可以解决此问题,例如:
Car &findCar(const string &name) {
...
// return if found, else throw
if (found it) {
return thecar; // assuming `thecar` means some already-existing object,
// if it's a local variable then return by value!
} else {
throw std::runtime_error(name);
}
}
来电者:
Car c = findCar("beetle");
或Car &c = findCar("beetle");
如果他们想要“看到”找到的实际对象而不是它的副本。如果findCar
希望调用者只看到副本而不是某个内部对象,那么当然可以按值而不是通过引用返回 - 函数签名中的差异为&
。
某处某人必须处理异常。
如果你更愿意避免异常,那么从find
函数返回的正确的东西是指针(或其他迭代器)。这是标准容器和算法在搜索时所做的事情,并且有一些特殊值(结束迭代器,或者你可以使用空指针),这意味着“找不到”。
答案 1 :(得分:2)
每当存在一个对象变量(不是指针或引用)时,它就包含对象的整个数据,这意味着它必须始终被初始化,所以是的,你必须使用你建议的解决方案之一
顺便说一句,如果你不使用指针或引用,你也不能将派生类的对象存储在变量中,所以我建议切换到指针。
答案 2 :(得分:1)
只要将对象声明为变量,就会初始化对象。
如果你想要延迟初始化,你必须使用指针和:
Car *c;
bool findCar(string name, Car * &out){
...
out = new Car();
}
不要忘记删除它
答案 3 :(得分:0)
不,这是不可能的。如果参数签名采用汽车参考,则必须指向汽车对象。你有两个解决方案,只有在右边创建对象,尽可能晚,使用这样的指针:
car* find_car(string name) {
...
return nullptr;
}
car* c = find_car(...);
if (c != nullptr) {
...
}
或使用例外,这可能不是你想要的
car find_car(string name) {
...
throw new runtime_error("car not found");
}
基本上将其声明为引用意味着您要保证对象已构造,因此需要提供。我会亲自使用指针。
答案 4 :(得分:0)
您可以从函数返回Car
:
struct Car
{
Car():_isValid(false){}
Car(const Car&);
bool isValid();
};
Car findCar (const string& name);
Car car = findCar("beetle");
if (car.isValid()){
...
}
如果throw
无法找到任何车型,其他变体是findCar
重复:
struct Car
{
Car(const Car&);
};
Car findCar (const string& name) {
....
if (noCarFound) throw CarNotFoundException();
....
}
try{
Car car = findCar("beetle") {
}
catch (CarNotFoundException e) {
....
}
或创建接受Car
string
构造函数
答案 5 :(得分:0)
我对C ++不是很有经验,但我也知道这不是最干净的解决方案。
然而,这是一种方法:
bool findCar(string name, Car **out) {
// first make out to null
*out = NULL;
...
// if found
if(found){
*out = &thecar;
return true;
}
// otherwise return false. Notice that out remains pointing null
return false;
}
现在,您应该拥有代码中的任何位置:
Car *c; // <- You don't create a new Car here!
if (findCar("beetle", &c)) {
...
}
希望你觉得有用