当前位置:  开发笔记 > 编程语言 > 正文

C++成员变量别名?

如何解决《C++成员变量别名?》经验,为你挑选了3个好方法。

我很确定这是可能的,因为我很确定我已经看到它完成了.我认为这很棒,但我很乐意接受"这是一个可怕的想法,因为____"的答案.

假设我们有一个基本结构.

struct vertex
{
    float x, y, z;
};

现在,我想在这些变量上实现别名.

vertex pos;
vertex col;
vertex arr;

pos.x = 0.0f; pos.y = 0.5f; pos.z = 1.0f;
col.r = 0.0f; col.g = 0.5f; col.b = 1.0f;
arr[0] = 0.0f; arr[1] = 0.5f; arr[2] = 1.0f;

理想情况下,第三种语法与数组无法区分.也就是说,如果我arr作为参考参数发送给期望其将存储数据的浮点数组的函数(例如许多OpenGL glGet函数),它将正常工作.

你怎么看?可能?可能但很愚蠢?



1> Ray Hidayat..:

我要做的是制作访问者:

struct Vertex {
    float& r() { return values[0]; }
    float& g() { return values[1]; }
    float& b() { return values[2]; }

    float& x() { return values[0]; }
    float& y() { return values[1]; }
    float& z() { return values[2]; }

    float  operator [] (unsigned i) const { return this->values_[i]; }
    float& operator [] (unsigned i)       { return this->values_[i]; }
    operator float*() const { return this->values_; }

private:
    float[3] values_;
}


这些方法是内联编写的,因此编译器应该优化成员函数调用并直接访问变量,因此它不是问题.我在Visual Studio 2008下编译了你的代码,由于你已经添加到类中的六个引用,它的大小增加了24个字节.如果意图是Vertex是一个轻量级的,它将通过值传递,那么这不是你想要的.

2> Adrian..:

联合中的无名嵌套结构不是标准的C++.但是,这应该有效:

struct Vertex
{
private:
   typedef float Vertex::* const vert[3];
   static const vert v;

public:
   typedef size_t size_type;
   float x, y, z;

   const float& operator[](size_type i) const {
      return this->*v[i];
   }

   float& operator[](size_type i) {
      return this->*v[i];
   }

};

const Vertex::vert Vertex::v = {&Vertex::x, &Vertex::y, &Vertex::z};

编辑:更多信息.该struct使用3个指针到数据成员的数组来访问重载[]运算符中的数据.

行"typedef float Vertex ::*const vert"表示vert是指向Vertex结构的float成员的指针.[3]意味着它是其中3个的数组.在重载的operator []中,对此数组进行索引,并取消引用指向数据的成员并返回值.

此外,无论打包问题如何,此方法都可以正常工作 - 编译器可以自由填充顶点结构,但它仍然可以正常工作.如果浮动包装不同,匿名联合将遇到问题.



3> Jonathan Lef..:

使用工会?

union vertex
{
    struct { float x, y, z; };
    struct { float r, g, b; };
    float arr[3];
};

我不推荐它 - 它会导致混乱.


补充:

正如Adrian在他的回答中所指出的那样,ISO C++不支持这种与匿名结构成员的联合.它适用于GNU G ++(当你打开' -Wall -ansi -pedantic' 时会抱怨不支持).它让人想起预先标准化的C天(K&R 1st Edn之前),当结构元素名称必须在所有结构中都是唯一的时候,你可以使用缩小的符号来获得结构中的偏移量,你可以使用其他结构类型的成员名称 - 一种无政府状态.当我开始使用C(很久以前,但后K&R1)时,这已经是历史用法了.

使用匿名联合成员(对于这两种结构)显示的符号由C11(ISO/IEC 9899:2011)支持,但不受早期版本的C标准支持.ISO/IEC 14882:2011(C++ 11)第9.5节规定了匿名联合,但GNU g++(4.9.1)不接受显示的代码-pedantic,标识" warning: ISO C++ prohibits anonymous structs [-Wpedantic]".

由于这个想法会导致混乱,我并不特别担心它不标准; 我不会使用这个机制来完成这个任务(我会对在联合中使用匿名结构感到谨慎,即使它是有益的).


提出了一个问题:

三个(xyz,rgb和数组)不一定对齐.

它是一个有三个要素的联盟; 这三个元素从同一地址开始.前两个是包含3个浮点值的结构.没有继承,也没有虚拟函数来提供不同的布局等.结构将以三个连续的元素排列(实际上,即使标准允许填充).该数组也从相同的地址开始,并且在结构中经历"无填充",元素与两个结构重叠.我真的没有看到会出现问题.

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有