函数在c ++中返回此指针

时间:2011-04-20 11:15:37

标签: c++

第一个代码:

#include <iostream>
using namespace std;
class demo
{
  int a;
public:
  demo():a(9){}
  demo& fun()//return type isdemo&
  {
    return *this;
  }
};

int main()
{
  demo obj;
  obj.fun();
  return 0;
}

第二段代码:

#include <iostream>
using namespace std;
class demo
{
  int a;
public:
  demo():a(9){}
  demo fun()//return type is demo
  {
    return *this;
  }
};

int main()
{
  demo obj;
  obj.fun();
  return 0;
}

这两个代码有什么不同,因为两个代码都在gcc中工作?我是新来的,所以如果我的提问方式错误,请原谅我。

6 个答案:

答案 0 :(得分:8)

demo & fun()返回对当前对象的引用。 demo fun()返回对象,由复制当前对象。

答案 1 :(得分:5)

除了@Erik关于返回类型的说法之外,this上的一点点指示 - 指针:
以下是等效的:

struct my_struct{
  my_struct* get_this() const { return this; }
};

my_struct obj;
my_struct* obj_this = ob.get_this();

std::cout << std::boolalpha; // to display true/false instead of 1/0
std::cout << "&obj == obj_this = " << &obj == obj_this << "\n";

this指针只是指向该对象的指针,您可以将其视为隐藏参数。以C方式更容易理解:

typedef struct my_struct{
  int data;
  // little fidgeting to simulate member functions in c
  typedef void (*my_struct_funcptr)(struct my_struct*,int);
  my_struct_funcptr func;
}my_struct;
// C++ does something similar to pass the this-pointer of the object
void my_struct_func(my_struct* this, int n){
  this->data += n;
}

my_struct obj;
obj.data = 55;
// see comment in struct
obj.func = &my_struct_func;
obj.func(&obj, 15);
//       ^^^^ - the compiler automatically does this for you in C++
std::cout << obj.data; // displays 70

答案 2 :(得分:4)

两者都有效但不同。在第一种情况下demo& fun()返回对同一对象的引用,在第二种情况下,创建一个新对象。虽然两者都相同,但语义不同,运行此示例:

#include <iostream>
struct test {
  int x;
  test() : x() {}
  test& foo() { return *this; }
  test bar() { return *this; }
  void set( int value ) { x = value; }
};
int main() {
  test t;
  t.foo().set( 10 );             // modifies t
  t.bar().set( 5 );              // modifies a copy of t
  std::cout << t.x << std::endl; // prints 10
}

答案 3 :(得分:1)

在代码1 demo obj中创建一个新的演示副本。 obj使用demo的默认构造函数'demo()初始化:a(9){}'。 obj.fun()会返回对(已存在的)obj的引用。

在代码2中obj.fun()使用demo的复制构造函数创建一个新的demo类型对象(在您的情况下,它是编译器生成的)并将该副本返回给调用者。

答案 4 :(得分:1)

Consider your function. demo fun(){return *this;} Here you are returning by value so one temporary object will be created which will be destroyed, once you assign the return value of fun to some other object. While in case when you pass the reference, no object will be created newly, but it will pass actual object and even after assigning function return value object will not destroy till main object(used inside fun, in ur case its the object calling the function) won't go out of scope. The concept you are trying to understand can be explained in more detail with other example. consider function that is taking object as argument and returning object as argument.(also consider we have object that contains a pointer, we will assign value to pointer by first allocating memory to pointer and a destructor, which will free memory hold by pointer of object). Now when you return object as pass by value, temporary object will be created, that will have exact copy of main object(and temporary object's pointer will also point to same address or you can say holds the same address). Now inside main(), you assign/initialize any object with return value(object) of function. But when your temp object will be destroyed after assigning value, it will also free the memory because of destructor and when you try to fetch the same address value through assigned object(inside main() ) you will get error as that memory has been already freed. But if you would have return value using reference, object returned by object won't destroy as main obj(inside function or through which we have called the function) is in scope and your pointer won't loose its memory. Making possible for assigned object to fetch address value through its pointer and avoid undesirable result.

答案 5 :(得分:0)

两个代码都有效。

  1. 第一个代码fun()正在返回对当前对象的引用
  2. 第二个代码fun()正在返回对象
  3. 的副本(按值)
  4. 对于第一种情况,如果您决定按值返回 然后更喜欢返回const 参考;即const demo& fun(); 以后你可以根据需要复制它。 简单地返回参考使得 对象可修改,可能 无意中编辑内容 意图
  5. 对于第二种情况,请勿按值返回对象, 因为它可以创造不必要的 临时副本将影响 代码的内存/性能