1

是否允许公开引用私有类成员?我知道,以下代码将编译,并且在我使用它时,它在 99% 的情况下都有效。问题是,我确实遇到了一些配置,其中对私有变量的 const 引用返回了错误的数据,即使与 POD 一起使用也是如此。那么,它是否存在一些一般性问题 - 语法错误或其他一些可能失败的情况?使用 const 引用相对于使用 Get() 方法是否有任何性能优势?请参阅以下代码中的注释...从“良好的编码风格”的角度来看,这是如何看待的?“好的实践”怎么样?

自己的研究:嗯,在使用简单数据类型时,更喜欢 const 引用而不是 Get() 方法可能没有性能优势。在使用大型结构时,仅返回一个引用可能很有用。Const ref 可能会破坏良好的 OOP 规则(封装和生命周期)。

但同样,基本问题是:即使在有效(现有)实例上使用,“const int &Width”是否有任何理由失败?从 dll 中导出类 CTest 怎么样?谢谢

class CTest
{
public:
  // public reference to a private variable - is this allowed? What about standards, what about 'good coding'?
  const int & Width; // read only property

  // Is there some performance penalty for GetWidth1() compared to previous reference Width?
  /*(inline)*/ int GetWidth1() const { return _width; } 

  // some performance benefit or disadvantage writting GetWidth2 rather than GetWidth1()?
  const int & GetWidth2() const { return _width; } 

  CTest(int width):
    Width(_width), // initialize public reference to a private variable - is this correct?
    _width(width)  // initialize member variable
  {}
private:
  int _width;
};

int main()
{
  CTest cTest(10);
  CTest * pTest = new CTest(10);

  int width1 = cTest.Width; // is this possible? Is there some reason (not) to use such a construction?
  int width2 = pTest->Width;
  int width3 = pTest->GetWidth1(); // of course, correct. But is there some performance penalty compared to pTest->Width?

  return 0;
}
4

2 回答 2

2

是否允许公开引用私有类成员?

是的,这本身并没有错。如果您已经看到它“返回错误数据”的情况,这意味着其他地方出了问题 - 可能是内存损坏,或者在数据成员初始化之前访问引用,或者在其目标被破坏后使用悬空引用.

最大的问题是引用是不可分配的,因此任何包含引用的类也不是。

使用 const 引用相对于使用 Get() 方法是否有任何性能优势?

我希望使用内联函数而不是引用会带来好处。类实例中没有任何东西要存储,也不需要任何运行时间接 - 它应该与直接访问数据成员一样有效。因此,我建议您不要使用参考成员。

从“良好的编码风格”的角度来看,这是如何看待的?“好的实践”怎么样?

通常,对数据成员的访问可能表明该类没有很好地封装。好的(面向对象的)实践通常根据接口的作用来指定接口,而不是根据它使用的数据来指定接口。但这是非常笼统的建议。有时最好的设计确实需要访问数据;但是为了提高效率,您应该通过公共数据成员或内联访问器函数来允许它。

于 2012-12-03T13:49:13.970 回答
1

当然允许公开对私有数据的引用。正确使用时也可以正常工作。但是请注意,它可能会比提供对变量的访问的内联函数更慢,因为在大多数情况下,编译器实际上存储了一个指针或引用来表示引用。使用存储间接的成本增加了对象大小和额外的取消引用。当您说它失败时,我怀疑您没有正确初始化引用,例如,在使用复制构造函数时。

顺便说一句,main()总是返回int(尽管返回语句可以省略)。

于 2012-12-03T13:43:10.383 回答