【问题标题】:Storing lvalue reference to a dynamically allocated array将左值引用存储到动态分配的数组
【发布时间】:2012-07-07 10:40:44
【问题描述】:

考虑下面的自定义数组类

template <typename element, unsigned int size>
class array
{
private:
    element (&data)[size];
public:
    array(element (&reference)[size]):data(reference){}
    array():data(new element [size]){} // This is where my problem arises
};

显然,在构造函数的初始化列表中,将右值表达式(new-expression)计算为指针的右值而不是引用类型。所以在MSVC(Microsoft Visual Studio 2012 RC)中提示类型从element *element(&)[size]的转换错误>

但是,我认为如果我可以将右值从指针转换为引用,它应该可以编译。有没有机会在构造函数的初始化列表中实现它?或者也许这一切都与 C++ 语言的原则相冲突?我已经调查了 reinterpret_cast,但我认为唯一相关的规则是

"T1 类型的左值表达式可以转换为引用 另一种类型 T2。结果是一个左值或 xvalue,指的是 与原始左值相同的对象,但类型不同。” - cppreference.com

明确指出转换适用于左值表达式

好的,我知道你现在可能会怎么想——你为什么需要这样的自定义数组类,为什么不直接使用复合指针而不是有问题的引用呢?嗯...在知道最好的方法之前,您总是需要选择不同的方法,不是吗?

【问题讨论】:

  • 假设您可以以某种方式转换new 的结果以适合您的用例。你怎么能正确删除它?
  • 这个问题与右值引用无关,我也看不到C++11特有的东西。
  • @Mat 你明白了;D。实际上,类中有一个标志,指示数据是否是包装的引用。如果它包装,它不会删除。否则它会。为方便起见,我在此处发布的课程没有出现。
  • @Yang:这是一种反模式。您应该重新设计,以便该类执行一项任务,而不必关心是否要释放内存。
  • @DavidRodríguez-dribeas 在一种情况下这种模式很有用。假设发明了基于 C++ 的动态或弱类型语言,并且用户不希望在声明此数组类型的变量时新建或删除,则必须在构造时管理内存分配。尽管如此,我当然不会在严肃的工作中使用它:-)。

标签: c++


【解决方案1】:

C++11 和右值引用是怎么回事?要获取指针指向的值的左值表达式,只需使用一元 * 运算符。从一开始它就是语言的一部分。在这里你要做的就是确保你得到一个指向数组的指针,而不是指向数组第一个元素的指针。

template <typename element, unsigned int size>
class array
{
private:
    element (&data)[size];
public:
    array() : data(*new element[1][size]) { }
    array(element (&reference)[size]) : data(reference) { }
};

正如 Mat 在他的评论中提到的,这里的无参数构造函数是一个非常糟糕的主意,因为内存不会被释放。希望拥有一个有效的代码示例可以让您进行一些实验并得出相同的结论。

【讨论】:

  • 嗯...我猜是别人。
  • 谁来删除内存,为什么我的方案比这个不好?
【解决方案2】:

您根本没有在此代码中使用 R 值引用。 &amp;&amp; r-value 符号没有一次使用。

编辑:

template <typename element, unsigned int size> 
class array 
{ 
private: 
    element (&data)[size]; 
    static element DefaultArrRef[size];
public: 
    //array(element (&reference)[size]):data(reference){} 
    array():data(DefaultArrRef){}
}; 


template <typename element, unsigned int size> 
element array<element,size>::DefaultArrRef[size];

【讨论】:

  • 您将data 定义为一个数组,而不是对数组的引用。这是个好主意,但与所要求的有很大不同。
  • 你的意思是:int (&amp;ref_array)[10]; - 这是不可能的。
  • 这是完全有效的,并且正是问题所在。
  • @Ajay hvd 准确地说。类包含的是引用,而不是数组本身。
  • 这仍然与问题中的代码完全不同。在这种方法中,调用默认构造函数的所有array 实例都将共享​​>同一个数组,而在问题的代码中,每个实例都拥有自己的单独数据。
猜你喜欢
  • 2020-02-09
  • 2021-11-03
  • 2012-05-21
  • 1970-01-01
  • 2021-07-14
  • 2013-12-18
  • 1970-01-01
  • 2020-08-07
  • 1970-01-01
相关资源
最近更新 更多