簡體   English   中英

函數在c ++中返回此指針

[英]function returning this pointer in 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中工作?我是新來的,所以請原諒我,如果我的提問方式是錯誤的。

demo & fun()返回對當前對象的引用。 demo fun()返回一個對象,通過復制當前對象來生成。

除了@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

兩者都有效但不同。 在第一種情況下, 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
}

考慮你的功能。

demo fun(){return *this;}

在這里,您將按值返回,因此一旦您將fun的返回值分配給其他對象,將創建一個將被銷毀的臨時對象。

在你傳遞引用的情況下,沒有任何對象會被新創建,但它會傳遞實際對象,甚至在賦值函數后返回值對象也不會破壞直到主對象(在內部使用fun,在你的情況下它是調用函數的對象) )不會超出范圍。

您嘗試理解的概念可以通過其他示例更詳細地解釋。 考慮將對象作為參數並將對象作為參數返回的函數。(也考慮我們有包含指針的對象,我們將通過首先將內存分配給指針和析構函數來為指針賦值,這將釋放對象指針釋放內存)。 現在,當您將對象作為值傳遞返回時,將創建臨時對象,該對象將具有主對象的精確副本(並且臨時對象的指針也將指向相同的地址,或者您可以說保持相同的地址)。 現在在main()中,您可以使用函數的返回值(對象)分配/初始化任何對象。 但是當你的臨時對象在分配值后被銷毀時,它也會因為析構函數而釋放內存,當你試圖通過指定的對象(在main()內部)獲取相同的地址值時,你會得到錯誤,因為內存已經存在釋放。

但是如果你有使用引用的返回值,對象返回的對象將不會破壞,因為主要的obj(內部函數或通過它調用函數)在范圍內,你的指針不會丟失它的內存。 使指定的對象可以通過其指針獲取地址值,並避免不良結果。

在代碼1中, demo obj創建了一個全新的demo。 使用demo的默認構造函數'demo()初始化obj :a(9){}'。 obj.fun()返回對(已存在的) obj的引用。

在代碼2中, obj.fun()使用demo的復制構造函數創建一個新的demo類型對象(在您的情況下,它是編譯器生成的)並將該副本返回給調用者。

這兩個代碼都有效。

  1. 第一個代碼fun()返回對當前對象的引用
  2. 第二個代碼fun()返回對象的副本(按值)
  3. 對於第一種情況,如果您決定按值返回,則更喜歡返回const引用; const demo& fun(); 以后你可以根據需要復制它。 簡單地返回引用使得對象可修改,這可能意外地編輯內容而沒有意圖
  4. 對於第二種情況,請勿按值返回對象,因為它可能會創建不必要的臨時副本,從而影響代碼的內存/性能

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM