2009-12-28 59 views
1

有人能告訴我(*ptr).fieldptr->field有什麼不同嗎? 我知道它連接不知何故靜態和動態鏈接,但我不知道它是什麼。 有人可以告訴我的差異,給我一個例子嗎?會員訪問區別

編輯: 如果我有這樣的代碼:

Point p;  //point is a class that derive from class shape 
Shape *s=&p; 
       //there is a diffrence if i write: 

(*s).print(); //print is virtual func 
s->print(); // the answers will not be the same, why? 

TNX!

+0

你是指'(* ptr).field'還是'* ptr.field'?如果你確實是指'* ptr。那麼這兩種形式完全沒有共同之處,這使得這個問題變得毫無意義。 – AnT 2009-12-28 20:24:25

+0

我的意思是(* ptr).field – aharon 2009-12-28 20:39:24

+0

從您的編輯:答案將是相同的。見下文。 – 2009-12-28 20:57:17

回答

4

它無關與靜態或動態鏈接 兩個表達式將返回ptr.field的值

的ptr->字段的形式是直接從一個接入指針成員的縮寫語法

UPDATE:它發生,我認爲你的初衷是不連接但結合 如果這確實是你是瞄準再有就是靜態綁定動態綁定 它們與 - >運算符有一些關係see here

+1

是的,但縮寫爲(* ptr).fld,不適用於* ptr.field。 – ChrisInEdmonton 2009-12-28 20:09:23

+1

需要注意的是,由於可能會在C++中重載operator *和operator->,所以這些並不一定等價。 – HostileFork 2009-12-28 20:15:25

+2

@Hostile Fork:這就是爲什麼在一些商店中,C++代碼審查會話應該包括電擊治療機器。 – 2009-12-28 21:00:29

2

靜態鏈接是鏈接器將程序中使用的所有庫例程複製到可執行映像的結果。這可能需要比動態鏈接更多的磁盤空間和內存,但速度更快,可移植性更高,因爲它不需要運行系統的庫。

動態鏈接是通過將可共享庫的名稱放在可執行映像中完成的。直到圖像運行,當可執行文件和庫都放在內存中時,纔會與庫例程實際鏈接。動態鏈接的一個優點是多個程序可以共享庫的一個副本。

但是它與你提到的指針間接無關 - 事實上,這兩個表達式是相同的。

+1

不完全。 ptr->字段與(* ptr).field相同,而不是* ptr.field。 – ChrisInEdmonton 2009-12-28 20:10:10

0

它們都是一樣的。
*ptr.field解除引用變量ptr然後返回成員field的值。

->運算符是上述的簡寫符號。

+2

實際上,'* ptr.field'被評估爲'*(ptr.field)',而不是'(* ptr).field'。 – 2009-12-28 19:59:51

1

這與鏈接無關。

ptr->fld 

(*ptr).fld 

這是純粹的語法糖僅僅是速記;)

+0

特別是,參見C++標準的第5.2.5.3節。 – outis 2009-12-28 20:01:46

+1

§5.2.5 3如果E1的類型爲「指向classX的指針」,則表達式E1-> E2被轉換爲等效形式 (*(E1))。 5.2.5的剩餘部分將僅解決第一個選項(點)。 – outis 2009-12-28 20:06:14

+0

@outis:你引用的部分描述* built-in *運算符' - >'的行爲。不要忘記,C++中的' - >'不一定是指內置的運算符。它也可以被用戶超載。 OP沒有說'ptr'是原始指針類型。 – AnT 2009-12-28 20:12:26

2

我認爲通過*ptr.field你的意思(*ptr).field

只考慮內置操作符,兩者沒有區別。不,它與這些術語暗示的無關和「靜態」或「動態」鏈接無關。

在兩者之間的唯一電勢差的是,在變型ptr->field->是C中的重載的運算符++,而在(*ptr).field變體僅*是重載,而.不是。

此外,這兩種成員訪問方法之間的一些差異存在於C語言(CRM C)的非常陳舊的版本中,但我懷疑今天任何人都關心這些。

1

只要ptr是一個指針,一旦加了括號(正如其他人所說的),兩者是等價的。如果ptr是一個對象而不是指針,則它們可能會有所不同,具體取決於來自對象的類或祖先的operator*operator->(如果有)的定義。

+0

好的,如果我有這樣的代碼: Point p; // point是一個派生自類形狀的類 Shape * s =&p; 有一個diffrence如果我寫(* S).PRINT(); //打印是虛擬FUNC 到S->打印(); 答案不會一樣,爲什麼? – aharon 2009-12-28 20:32:01

7

這與靜態或動態鏈接無關。

請參閱C++'s operator precedence.的優先級低於*,所以實際上*ptr.fldptr->fld之間的差異很大。例如,下面的代碼演示:

#include <iostream> 

struct foo { 
    int f; 
}; 

int main() { 
    struct foo *p = new struct foo; 
    p->f = 42; 
    std::cout << p->f << std::endl; 
    std::cout << (*p).f << std::endl; 
    // The following will not compile 
    // std::cout << *p.f << std::endl; 
} 

正如約翰Knoeller指出,ptr->fld(*(ptr)).fld語法糖,但不一樣的*ptr.fld,這實際上會評估爲*(ptr.fld),可能不是你想要什麼。

當你有一個指向結構的指針並且想訪問其中包含的字段時,你會使用ptr->fld(*(ptr)).fld意味着同樣的事情,但不是很整齊。當你有一個結構體,而不是一個指向結構體的指針時,你會使用*strct.fld,該結構體包含一個字段(fld),它是一個要解除引用的指針。上面顯示了ptr->fld的情況。的*strct.fld的情況下可以用以下結構中:

struct foo { 
    int *fld; 
} 

struct foo f; 
f.fld = new int; 
*f.fld = 42; 
+0

正如outis所指出的,ptr->字段實際上是(*(ptr))字段的合成糖,而不是(* ptr).field。糟糕!固定。 – ChrisInEdmonton 2009-12-28 20:12:57

+0

既然'ptr'是一個標識符,'(* ptr).field'就可以了。不過,指出一般情況是很好的。 – outis 2009-12-28 20:37:04

+0

OP確認他實際上是指'(* ptr).field'。我編輯了這個問題。 – AnT 2009-12-28 20:40:54

1

的形式 - >僅僅是用於解refrencing指針和訪問構件的簡寫。

(*ptr).field; 
// Equiv to 
ptr->field; 

一個很好的理由使用 - >是,當你在下面的鏈條:

int x = (*(*(*(*ptr).field1).field2).field3).field4; 
// Equiv to 
int y = ptr->field1->field2->field3->field4; 

第二個變得更具有可讀性。

至於你的問題的第二部分。
我覺得很簡單,只是一個例子。

#include <iostream> 

class Shape 
{ 
    public: virtual ~Shape()  {} 
       virtual void Print() {std::cout << "Shape\n";} 
}; 
class Point: public Shape 
{ 
    public: virtual void Print() {std::cout << "Point\n";} 
}; 

int main() 
{ 
    Point p; 
    Shape* s = &p; 

    s->Print(); 
    (*s).Print(); 
} 

> vi x.cpp 
> g++ x.cpp 
> ./a.exe 
Point 
Point 

正如你所看到的結果在兩種情況下都是一樣的。

當您通過指針或引用調用方法時,將調用虛擬調用機制。星運算符(AKA derefence運算符)返回一個對象的引用(它實際上不引用對象)。所以當它用於調用方法時,將調用虛擬調用機制並調用該方法的最派生版本。

+0

好吧,坦克,雖然我的DR。說有一些不同,但我不記得是什麼... – aharon 2009-12-28 21:29:31

+0

(* ptr) - > f1和ptr-> f1沒有區別。這是由標準定義的。如果我們轉向虛擬功能。在這種情況下,虛擬調用機制不會被使用,但這不是其中之一。 – 2009-12-28 21:43:06

+0

那麼virtal調用機制將不會被使用的情況如何? – aharon 2009-12-29 06:47:47