C++中指针类型转换的解释

Posted

技术标签:

【中文标题】C++中指针类型转换的解释【英文标题】:Explanation of typecasting of pointer in C++ 【发布时间】:2014-08-14 14:30:48 【问题描述】:

我不理解我在此处提供的代码中提到的以下两行。为什么我需要使用int*?我如何访问私有变量?我不确定我在用这两行做什么。请详细说明。

有问题的线路:

int *p = (int *) &s;  
*p=10;

主代码:

#include <iostream>

using namespace std;

class sample 
private:
  int a;
public:
  void function () 
    a=5;
  
  void printA () 
    cout<<"value is "<<a<<endl;
  
;

int main () 
  sample s;
  s.function();
  s.printA();

  int *p = (int *) &s;
  *p=10;

  s.printA();

【问题讨论】:

你只需简单地添加任何虚拟方法,在 VS 和 gcc "a" 不会改变。 【参考方案1】:

使用(int*) 是一个非常糟糕的主意。您正在使用一个不是 int 的类作为 int。哪个不好。

您不能访问私有成员,也不应该访问,这就是它们是私有的原因。

int *p = (int *) &s;  
*p=10;

这意味着,您有一个对象s,类型为sample,并且它有一个数据成员int a;。您写的内容有效,因为a 恰好在课程的开头。

在某些情况下,类的布局是有保证的,你可以在这里阅读:

What are POD types in C++? What are Aggregates and PODs and how/why are they special?

【讨论】:

【参考方案2】:

首先,请不要这样做。

您正在利用 sample 类的内存布局。第一个成员是int,它位于类内存空间的开头。

尝试在a 之前添加另一个int,您会发现a 没有改变。

【讨论】:

【参考方案3】:

此代码试图通过在指针转换的帮助下打破类强加的封装来访问类sample 中的成员a。它不安全,因为它取决于类成员的内存布局。

假设成员 a 将位于 sample 对象的起始位置,因此获取对象的地址并将其转换为 int* 将可以访问第一个 @ 987654326@会员。

这是有效的,因为a 确实位于第一位,但这并不能保证,并且由于填充/对齐以及继承层次结构的原因,这对其他成员不起作用。这种代码很危险。

如果需要,您应该拥有私有成员的访问器/修改器,而不是编写此类代码来访问它们。

【讨论】:

“这不能保证” - 是的(自 C++11 起),除非您更改类使其不再是标准布局。我同意这是危险的,因为这样的更改会默默地破坏代码;但是如果你真的需要的话,你可以(可移植地)依赖于这样一个类的布局。

以上是关于C++中指针类型转换的解释的主要内容,如果未能解决你的问题,请参考以下文章

c和c++中,对结构体进行强制类型转换!

C++四种类型转换

C++四种类型转换

类型转换 c++ 指针和非类型转换指针指向相同的位置,但给出不同的值

reinterpret

如何将指针转换为我在 C++ 中输入的类型?