会员访问差异

发布于 2024-08-16 02:19:51 字数 422 浏览 2 评论 0原文

有人可以告诉我 (*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!

can someone tell me what is the different between (*ptr).field and ptr->field?
I know it connect somehow to static and dynamic linking, but i dont know what is it.
can someone tell me the differnet and give me an example?

edit:
if i have this code:

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

笑忘罢 2024-08-23 02:19:51

这与静态或动态链接无关。

请参阅 C++ 的运算符优先级. 的优先级低于 *,因此 *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;
}

正如 John Knoeller 指出的,ptr->fld(*(ptr)).fld 的语法糖,但不是与 *ptr.fld 相同,它实际上会计算为 *(ptr.fld),可能不是您想要的。

当您有一个指向结构的指针并想要访问其中包含的字段时,您可以使用ptr->fld(*(ptr)).fld 含义相同,但不那么整洁。当您有一个结构体(而不是指向结构体的指针)且包含一个字段 (fld)(该字段是您想要取消引用的指针)时,您可以使用 *strct.fld 。上面显示了ptr->fld的情况。 *strct.fld 的情况可以与以下结构一起使用:

struct foo {
  int *fld;
}

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

This has nothing to do with static or dynamic linking.

See C++'s operator precedence. The . has a lower precedence than *, so there's actually quite a difference between *ptr.fld and ptr->fld. For example, the following code demonstrates:

#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;
}

As John Knoeller points out, ptr->fld is syntactic sugar for (*(ptr)).fld, but is not the same as *ptr.fld, which would actually evaluate to *(ptr.fld), probably not what you want.

You'd use ptr->fld when you have a pointer to a structure and want to access a field contained therein. (*(ptr)).fld means the same thing but is not as tidy. You'd use *strct.fld when you have a structure, not a pointer to a structure, that contains a field (fld) which is a pointer you want to dereference. The case of ptr->fld is shown above. The case of *strct.fld could be used with the following structure:

struct foo {
  int *fld;
}

struct foo f;
f.fld = new int;
*f.fld = 42;
怎樣才叫好 2024-08-23 02:19:51

它与静态或动态链接无关
两个表达式都会返回 ptr.field 的值

ptr->field 形式是直接从指针访问成员的缩写语法

更新:我发现您的原始意图不是链接,而是绑定
如果这确实是您的目标,那么就有静态绑定动态绑定
这与 -> 有一些关系运算符参见此处

it has nothing to do with static or dynamic linking
both expressions will return the value of ptr.field

the ptr->field form is an abbreviated syntax for accessing a member directly from a pointer

UPDATE: it occurred to me that your original intent was not linking but binding
if this indeed was what you were aiming to then there is static binding and dynamic binding
which have some relation to the -> operator see here

独享拥抱 2024-08-23 02:19:51

静态链接是链接器将程序中使用的所有库例程复制到可执行映像的结果。这可能比动态链接需要更多的磁盘空间和内存,但速度更快且更便携,因为它不需要运行它的系统上存在库。

动态链接是通过将可共享库的名称放入可执行映像中来完成的。直到运行映像(此时可执行文件和库都放置在内存中)时,才会发生与库例程的实际链接。动态链接的一个优点是多个程序可以共享库的单个副本。

但它与你提到的指针间接无关——事实上,这两个表达式是相同的。

Static linking is the result of the linker copying all library routines used in the program into the executable image. This may require more disk space and memory than dynamic linking, but is both faster and more portable, since it does not require the presence of the library on the system where it is run.

Dynamic linking is accomplished by placing the name of a sharable library in the executable image. Actual linking with the library routines does not occur until the image is run, when both the executable and the library are placed in memory. An advantage of dynamic linking is that multiple programs can share a single copy of the library.

But it is unrelated to pointer indirection you've mentioned -- in fact, those two expressions are identical.

西瑶 2024-08-23 02:19:51

我假设 *ptr.field 您的意思是 (*ptr).field

就仅考虑内置运算符而言,两者之间没有区别。不,它与“静态”或“动态”链接无关,无论这些术语暗示什么。

两者之间唯一的潜在区别是,在 ptr->field 变体中 -> 是 C++ 中的可重载运算符,而在 (*ptr) 中仅 .field 变体 * 是可重载的,而 . 则不可重载。

此外,这两种成员访问方法之间存在一些差异,这些差异存在于非常古老的 C 语言版本 (CRM C) 中,但我怀疑今天是否有人关心这些差异。

I assume that by *ptr.field you meant (*ptr).field.

As far as only built-in operators are considered, there's no difference between the two. And no, it has nothing to do with and "static" or "dynamic" linking, whatever is implied by these terms.

The only potential difference between the two is that in ptr->field variant -> is an overloadable operator in C++, while in the (*ptr).field variant only * is overloadable, while . is not.

Also, some differences between these two methods of member access existed in very archaic versions of C language (CRM C), but I doubt anyone cares about those today.

林空鹿饮溪 2024-08-23 02:19:51

这与链接无关。

ptr->fld 

只是

(*ptr).fld

It's pure syntical Sugar 的简写;)

This has nothing to do with linking.

ptr->fld 

is merely shorthand for

(*ptr).fld

It's pure syntactic sugar ;)

夜司空 2024-08-23 02:19:51

只要 ptr 是一个指针,一旦正确加上括号,两者就等效(正如其他人所说)。如果 ptr 是一个对象,而不是指针,则它们可能会有所不同,具体取决于 operator*operator->(如果有)的定义) 来自对象的类或祖先。

As long as ptr is a pointer, the two are equivalent once properly parenthesized (as others have said). If ptr is an object, rather than a pointer, they might be different depending on definitions for operator* and operator-> (if any) from the object's class or ancestors.

一身软味 2024-08-23 02:19:51

形式->只是取消指针引用和访问成员的简写。

(*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

正如您所看到的,两种情况下的结果是相同的。

当您通过指针或引用调用方法时,将调用虚拟调用机制。星号运算符(又名解引用运算符)返回对对象的引用(它实际上并不解引用该对象)。因此,当它用于调用方法时,将调用虚拟调用机制并调用该方法的最派生版本。

The form -> is just shorthand for de-refrencing the pointer and accessing the member.

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

One good reason for using -> is that when you are following a chain:

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

The second one becomes much more readable.

As for the second part of your question.
I find it really easy to just nock up an example.

#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

As you can see the result is the same in both situations.

When you call a method via a pointer or a reference the virtual call mechanism will be invoked. The star operator (AKA derefence operator) returns a reference to an object (it does not actually de-reference the object). So when it is used to call a method the virtual call mechanism will be invoked and the most derived version of the method called.

明明#如月 2024-08-23 02:19:51

它们都是一样的。
*ptr.field 取消引用变量 ptr,然后返回成员 field 的值。

-> 运算符是上述内容的简写符号。

They are both the same.
*ptr.field dereferences the variable ptr then returns the value of member field.

The -> operator is shorthand notation for the above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文