引用是否与指针正交?

时间:2017-06-07 06:55:35

标签: c++

这个问题意味着语言正交(因为缺乏冗余)特征。 C ++ 中的引用(从不为null [1])可以用指针实现,而编译器检查语义差异。像Java或C#这样的语言只有引用(可能为null)但没有指针而C则反过来。因此,对于完整的语言来说,这是足够的。 C ++中的行为是否足够正交?

[1]您可以取消引用nullptr,但这是未定义的。

3 个答案:

答案 0 :(得分:1)

由于参考折叠规则(§8.3.2),引用已成为 非常有用;他们现在支持“完美转发”的东西 可能有指针。例如:

template<typename T>
class some_container
{
public:
    // ... lots of other stuff
    template<typename... Args>
    void emplace_back(Args&&... args)
    {
        T* ptr = find_slot_for_new_data();
        new (ptr) T( std::forward<Args>(args)... );
    }
};

这将构建一个T就地,(emplace_xxx是委托构造函数) 并且它将使用“完美转发”这样做,即;

推导出T&&

T将保留:

  • 价值类别
  • cv修饰符

使用指针无法做到这一点。

答案 1 :(得分:-2)

引用只不过是C ++中更严格的指针,因为您可以通过获取其地址来“转换”对指针的引用。 这远不是说它们是多余的,但它们与正交相反。他们基本上做同样的事情。

答案 2 :(得分:-2)

这是指针和要考虑的引用之间的区别。

.rdd

对战

#include <vector>

int main() {
   // Compiles and it contains pointers to ints 
   std::vector<int*> vpInts; 
   return 0;
}

第二种情况是非法的,特别是在MSVS的MSVS2017 CE编译错误中显示。

#include <vector>

int main() {
    // Does not compile
    std::vector<int&> vrInts;
    return 0;
}

基本上在C ++中,指针本身是一个声明的变量,它占用堆栈或堆上的内存,其中引用可能会或可能不会引用已经创建的对象或已经在内存中的变量。这取决于编译器如何处理它;一些编译器将通过在寄存器中输入和弹出值来使用移动语义来优化内存占用,而指针变量将始终占用指定的内存量。有一些相似之处,即指针确实指向另一个变量或对象的内存地址,并且引用引用已创建的另一个变量或对象的实例的内存地址。