在C++中C的双指针的等价物是什么?

Ran*_*Bob -4 c++ c++11

我是一个C/C++新手,很抱歉,如果我的问题看起来很简单.

一直声称C++中的指针是无用的.例如,请参阅Konrad Rudolph的答案https://softwareengineering.stackexchange.com/questions/56935/why-are-pointers-not-recommended-when-coding-with-c

下面我有一个例子,我想知道如何在不使用任何指针的情况下用C++代码替换C代码:

  double *A;                              
  double **a;

  A=new(std::nothrow) double[4];

  a=new(std::nothrow) double*[2];

for (unsigned int q=0, k=0; k < 2; k++)
    {
        a[k]=A + q;
        q+=2;
    }

  delete[] A;
 delete[] a;
Run Code Online (Sandbox Code Playgroud)

程序员如上编码,因为他/她需要指针a指向指针,A以便在修改变量时A,他/她不会修改a.

有时,程序员for loop使用[k]从k = {0,1,2,3}进行a,有时他for loop从i 得到双a [i] [j],j = {0,1}.

如何在不使用指针的情况下用C++代码替换它?

Xir*_*ema 7

一些重要的清晰度:你被建议的是不使用Raw,Owning Pointers.如果您知道事实上您不负责delete所述内存,那么使用非拥有原始指针是完全可以的.或者拥有智能指针如果你对所述内存负责,但是delete将由智能指针类的RAII原则处理.

那么让我们考虑一下代码中发生了什么:

  • A表示对运行时大小的doubles 数组的所有权.
  • a表示对doubles 的运行时大小的非拥有指针数组的所有权,所有这些指针都来自A.

简单地创建一个对象数组最好std::array用于编译时大小的数组,或者std::vector用于运行时大小的数组.所以我们需要后者.这很容易构建:

std::vector<double> A(4);//Array of 4 doubles.
Run Code Online (Sandbox Code Playgroud)

因为a将包含非拥有指针A,我们知道a它会比这更长,所以在这个向量中使用原始指针是完全正常的:

std::vector<double*> a(2);
Run Code Online (Sandbox Code Playgroud)

然后,我们分配到它,就像你的代码已经在做:

//Use size_t for sizes in C++. Always, always, always.
for (size_t q = 0, k = 0; k < 2; k++){
    a[k] = A + q;//Uh oh, this doesn't compile!
    q += 2;
}
Run Code Online (Sandbox Code Playgroud)

啊,嗯.A不再是原始指针了.好吧,我们需要使用成员函数std::vector来获取原始指针.

//Use size_t for sizes in C++. Always, always, always.
for (size_t q = 0, k = 0; k < 2; k++){
    a[k] = A.data() + q;//There we go.
    q += 2;
}
Run Code Online (Sandbox Code Playgroud)

最后,因为我们的内存是RAII管理的,所以我们delete之后不需要这个内存:

//No longer needed
//delete[] A;
//delete[] a;
Run Code Online (Sandbox Code Playgroud)

所以最终的代码最终看起来像这样:

std::vector<double> A(4);
std::vector<double*> a(2);
for (size_t q = 0, k = 0; k < 2; k++){
    a[k] = A.data() + q;
    q += 2;
}
Run Code Online (Sandbox Code Playgroud)

此代码几乎与您最初编写的C风格代码完全相同,并且更易于阅读和维护.唯一的区别是少量的开销std::vector,编译器可以为最终程序优化.

如果您想要从字面上模拟原始代码行为的代码,那就是结果.我不推荐它,因为它比你需要的更复杂,并且限制了代码的使用方式,但如果你只是想要直接端口(或者只是想看看Smart Pointers如何适应这种问题),这里它是:

std::unique_ptr<double[]> A = std::make_unique<double[]>(4);
std::unique_ptr<double*[]> a = std::make_unique<double*[](2);
for (size_t q = 0, k = 0; k < 2; k++){
    a[k] = A.get() + q;
    q += 2;
}
Run Code Online (Sandbox Code Playgroud)

  • 甚至`std :: vector <double*> a {&A [0],&A [2]};`(带有`{}`而不是`()`). (2认同)