1

(*ptr).fieldとの違いは何ptr->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!

4

8 に答える 8

7

これは、静的リンクまたは動的リンクとは関係ありません。

C++ の演算子の優先順位を参照してください。は.よりも優先順位が低い*ため、実際には と の間にはかなりの違いが*ptr.fldありptr->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;
}

John 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;
于 2009-12-28T20:04:29.957 に答える
4

静的リンクまたは動的リンクとは関係ありません。両方の式は ptr.field の値を返します。

ptr->field 形式は、ポインターから直接メンバーにアクセスするための省略構文です。

更新:あなたの元の意図はリンクではなくバインディングであることがわかりました が、これが実際にあなたが目指していたものである場合 、 -> 演算子と何らかの関係がある 静的バインディング動的バインディングがあります here を参照してください

于 2009-12-28T19:54:22.680 に答える
2

*ptr.field私はあなたが意味したと仮定します(*ptr).field

組み込み演算子のみを考慮する限り、2 つの間に違いはありません。いいえ、これらの用語で暗示されているものは何でも、「静的」または「動的」リンクとは何の関係もありません。

2 つの唯一の潜在的な違いは、ptr->fieldVariant->は C++ でオーバーロード可能な演算子であるのに対し、(*ptr).fieldVariant ではのみ*オーバーロード可能であり、while.はそうでないことです。

また、メンバー アクセスのこれら 2 つの方法のいくつかの違いは、C 言語 (CRM C) の非常に古いバージョンに存在していましたが、今日、誰もそれらを気にかけているとは思えません。

于 2009-12-28T20:04:01.443 に答える
2

静的リンクは、リンカーがプログラムで使用されるすべてのライブラリ ルーチンを実行可能イメージにコピーした結果です。これには、動的リンクよりも多くのディスク容量とメモリが必要になる場合がありますが、実行されるシステムにライブラリが存在する必要がないため、高速で移植性が高くなります。

動的リンクは、共有可能なライブラリの名前を実行可能イメージに配置することによって実現されます。ライブラリ ルーチンとの実際のリンクは、実行可能ファイルとライブラリの両方がメモリに配置されるときに、イメージが実行されるまで発生しません。動的リンクの利点は、複数のプログラムがライブラリの 1 つのコピーを共有できることです。

しかし、あなたが言及したポインターの間接化とは無関係です。実際、これら 2 つの式は同一です。

于 2009-12-28T19:55:45.840 に答える
1

-> の形式は、ポインターの参照を解除してメンバーにアクセスするための省略形です。

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

-> を使用する正当な理由の 1 つは、チェーンをたどっている場合です。

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

2番目のものははるかに読みやすくなります。

あなたの質問の2番目の部分について。
例を思いつくのは本当に簡単だと思います。

#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

ご覧のとおり、どちらの状況でも結果は同じです。

ポインターまたは参照を介してメソッドを呼び出すと、仮想呼び出しメカニズムが呼び出されます。スター オペレーター (別名 derefence オペレーター) は、オブジェクトへの参照を返します (実際にオブジェクトを逆参照するわけではありません)。したがって、メソッドを呼び出すために使用されると、仮想呼び出しメカニズムが呼び出され、メソッドの最も派生したバージョンが呼び出されます。

于 2009-12-28T20:43:51.453 に答える
1

がポインタである限り、ptr(他の人が言ったように) 適切に括弧で囲まれると、2 つは等価になります。ptrがポインターではなくオブジェクトである場合、オブジェクトのクラスまたは先祖からの および (存在する場合) の定義によって異なる場合がありますoperator*operator->

于 2009-12-28T20:04:27.623 に答える
1

これはリンクとは関係ありません。

ptr->fld 

は単なる省略形です

(*ptr).fld

それは純粋な構文糖です;)

于 2009-12-28T20:01:00.797 に答える
0

どちらも同じです。
*ptr.field変数を逆参照してptrから、 member の値を返しますfield

演算子は、上記の->簡略表記です。

于 2009-12-28T19:56:51.797 に答える