C ++ - 通过传递函数初始化变量?

时间:2012-02-05 12:21:06

标签: c++ pass-by-reference

是否可以从返回参数初始化变量(通过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未初始化?

我想到的解决方案是:

  • 向Car添加廉价的0参数构造函数
  • 切换到指针(我宁愿避免)

6 个答案:

答案 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)) {
    ...
}

希望你觉得有用