将单个属性类转换为属性类型

时间:2015-04-23 07:32:24

标签: c++ casting

是否可以将只包含一个属性的类转换为属性类型?

此示例按预期打印1。但它能保证有效吗?

class A {
private:
    int x = 1;
};

int main()
{
    A a;
    cout << *((int*)&a) << endl; // (1)
    cout << *(int*)(((char*)&a)+offsetof(A, x)) << endl; // (2) //requires x to be public

    return 0;
}

修改
或者是否有另一种方法来访问a.x而不修改A?

2 个答案:

答案 0 :(得分:1)

无法保证(至少我没有在C ++规范中找到任何关于它的内容)但是通常的编译器实现首先将类或结构的第一个元素放在第一位,这样它就具有与结构本身相同的地址。

但是你会得到一个一般未定义行为的工作案例是否可接受取决于您的实际要求。示例:

  • 此代码只能在有限的环境中运行(您自己的机器或您控制的一些机器)=&gt;您只需记录事实并测试编译器版本的每次更改
  • 代码将包含在一个非敏感的应用程序中,该应用程序仅以二进制形式部署=&gt;用红色闪烁字体记录它,但你可以考虑使用它
  • 此代码将包含在一个合理的应用程序中,该应用程序将部署到许多不同的系统中=&gt;忘了吧

答案 1 :(得分:0)

最好的方法是实现相应的强制转换操作符:

class A
{
  private:
    int x = 1;
  public:
    operator int () const { return this->x; }
};

int main()
{
  A a;
  std::cout << (int)a << std::endl;
  return 0;
}

另一种解决方案可以是以下方面。它在代码中不那么具有侵入性,但我更喜欢前一个。

class A
{
  public:
      A(int x_) : x(x_) {}
  private:
    int x;
  friend class A_Caster;
};

class A_Caster
{
  private:
      const A& a;
    public:
      A_Caster(const A& a_) : a(a_) {}
      operator int () const { return this->a.x; }
};

int main()
{
  A a(10);
  std::cout << (int)A_Caster(a) << std::endl;
  return 0;
}