2012-01-18 77 views
19

我有一个名为Object的类,它存储了一些数据。如何在C++中通过引用返回类对象?

我想通过参考使用这样的函数返回它:

Object& return_Object(); 

然后,在我的代码,我会这样称呼它:

Object myObject = return_Object(); 

我已经写的代码这个和它编译。但是,当我运行代码时,我始终得到一个seg错误。什么是通过引用返回类对象的正确方法?

+1

不应该myObject是一个referrence? – 2012-01-18 17:28:52

+0

你可以在这里找到答案: http://stackoverflow.com/questions/3350385/how-to-return-an-object-in-c – MOHRE 2017-02-25 05:32:21

+0

你可以在这里找到方法:http://stackoverflow.com/问题/ 3350385 /如何返回一个对象在c – MOHRE 2017-02-25 05:34:16

回答

35

您可能正在返回堆栈中的对象。也就是说,return_Object()大概是这样的:

Object& return_Object() 
{ 
    Object object_to_return; 
    // ... do stuff ... 

    return object_to_return; 
} 

如果这是你在做什么,你的运气了 - object_to_return已经超出了范围,并在return_Object年底被破坏,所以myObject指到一个不存在的对象。您需要按值返回,或者返回在更广范围内声明的Object或返回到堆上的new

13

您只能通过引用返回非本地对象。析构函数可能会使某些内部指针无效,或者其他。

不要害怕返回值 - it's fast

18

您只能使用

 Object& return_Object(); 

如果返回的对象具有比功能的更大的范围内。例如,如果你有一个封装类的地方,你可以使用它。如果您在函数中创建一个对象,请使用指针。如果要修改现有对象,请将其作为参数传递。

class MyClass{ 
     private: 
     Object myObj; 

     public: 
     Object& return_Object() { 
      return myObj; 
     } 

     Object* return_created_Object() { 
      return new Object(); 
     } 

     bool modify_Object(Object& obj) { 
      // obj = myObj; return true; both possible 
      return obj.modifySomething() == true; 
     } 
    }; 
+0

但是,如果在我的调用代码中说:'MyClass mc; Object outsideObj = mc.return_Object;' 如果我然后修改'outerObj'的属性,那实际上是否修改了封装在'mc'内的'myObj'? – livefree75 2017-02-22 16:06:44

+0

Object outsideObj = mc.return_Object();将引发实例'outsideObj'的复制构造。它现在是一个单独的实例,并且修改一个会影响另一个实例,这取决于复制构造函数的实现方式。 – UmNyobe 2017-02-23 11:21:37

1

那么,它可能不是一个非常漂亮的代码解决方案,但它真的很漂亮,在你的函数接口中。而且它也非常有效。如果第二个对你更重要(例如,你正在开发一个库),这是理想的。

诀窍是这样的:

  1. 甲线A a = b.make();在内部转换为A的构造,即,如果你写A a(b.make());
  2. 现在b.make()应该产生一个带有回调函数的新类。
  3. 这整个事情可以很好地处理,只有类,没有任何模板。

这是我最小的例子。只检查main(),因为你可以看到它很简单。内部不是。

从速度的角度来看:一个Factory::Mediator类的大小只有2个指针,多于1个而不是更多。这是整个事物中唯一被价值转移的对象。

#include <stdio.h> 

class Factory { 
    public: 
    class Mediator; 

    class Result { 
     public: 
     Result() { 
      printf ("Factory::Result::Result()\n"); 
     }; 

     Result(Mediator fm) { 
      printf ("Factory::Result::Result(Mediator)\n"); 
      fm.call(this); 
     }; 
    }; 

    typedef void (*MakeMethod)(Factory* factory, Result* result); 

    class Mediator { 
     private: 
     Factory* factory; 
     MakeMethod makeMethod; 

     public: 
     Mediator(Factory* factory, MakeMethod makeMethod) { 
      printf ("Factory::Mediator::Mediator(Factory*, MakeMethod)\n"); 
      this->factory = factory; 
      this->makeMethod = makeMethod; 
     }; 

     void call(Result* result) { 
      printf ("Factory::Mediator::call(Result*)\n"); 
      (*makeMethod)(factory, result); 
     }; 
    }; 
}; 

class A; 

class B : private Factory { 
    private: 
    int v; 

    public: 
    B(int v) { 
     printf ("B::B()\n"); 
     this->v = v; 
    }; 

    int getV() const { 
     printf ("B::getV()\n"); 
     return v; 
    }; 

    static void makeCb(Factory* f, Factory::Result* a); 

    Factory::Mediator make() { 
     printf ("Factory::Mediator B::make()\n"); 
     return Factory::Mediator(static_cast<Factory*>(this), &B::makeCb); 
    }; 
}; 

class A : private Factory::Result { 
    friend class B; 

    private: 
    int v; 

    public: 
    A() { 
     printf ("A::A()\n"); 
     v = 0; 
    }; 

    A(Factory::Mediator fm) : Factory::Result(fm) { 
     printf ("A::A(Factory::Mediator)\n"); 
    }; 

    int getV() const { 
     printf ("A::getV()\n"); 
     return v; 
    }; 

    void setV(int v) { 
     printf ("A::setV(%i)\n", v); 
     this->v = v; 
    }; 
}; 

void B::makeCb(Factory* f, Factory::Result* r) { 
     printf ("B::makeCb(Factory*, Factory::Result*)\n"); 
     B* b = static_cast<B*>(f); 
     A* a = static_cast<A*>(r); 
     a->setV(b->getV()+1); 
    }; 

int main(int argc, char **argv) { 
    B b(42); 
    A a = b.make(); 
    printf ("a.v = %i\n", a.getV()); 
    return 0; 
}