在C ++中,C的双指针相当于什么?

时间:2018-08-08 19:17:37

标签: c++ c++11

我是C / C ++新手,很抱歉,如果我的问题似乎很简单。

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

参见Konrad Rudolph的答案。

下面有一个示例,我想知道如何在不使用任何指针的情况下用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;

程序员如上所述进行编码,因为他/她需要指针a指向指针A,以便在修改A指向的变量时,请勿修改a

有时候,程序员用k [{0,1,2,3}中的a [k]来做for loop,有时他做双for loop a [i] [j]来自i,j = {0,1}。

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

3 个答案:

答案 0 :(得分:7)

一些重要的说明:建议您不要使用原始拥有指针。最好使用非拥有的原始指针,前提是您知道,实际上,您无需delete分配所说的内存;或拥有智能指针(如果您负责所述内存),但是delete的处理将由智能指针类的RAII原则处理。

因此,让我们考虑一下代码中发生的事情:

  • A代表对double s的运行时大小数组的所有权。
  • a表示对运行时大小的double的非所有权指针数组的所有权,所有指针都来自A

对于编译时大小的数组,简单地创建对象数组最好用std::array表示,对于运行时大小的数组,最好用std::vector表示。因此,我们需要后者。这很容易构造:

std::vector<double> A(4);//Array of 4 doubles.

由于a将包含指向A的非所有权指针,我们知道该指针将比a失效,因此在此向量内使用原始指针是完全可以的:

std::vector<double*> a(2);

然后,就像您的代码已经在做的那样,我们将其分配给它:

//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;
}

啊,嗯。 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;
}

最后,由于我们的内存是由RAII管理的,因此我们以后不需要delete

//No longer needed
//delete[] A;
//delete[] a;

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

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;
}

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

如果您要使用从字面上看的代码模仿您原始代码的行为,则将是结果。我不建议这样做,因为它比您需要的要复杂得多,并且会限制代码的使用方式,但是如果您只需要直接端口(或者只是想了解智能指针如何解决此类问题),请点击此处是:

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;
}

答案 1 :(得分:1)

C语言中指针到指针的主要用途之一是返回指针值:

error_t Allocate Object(Object ** ptr);

虽然在C ++中同样有效,但是可以通过使函数采用引用指针而不是指针指针来使其更加直观:

error_t AllocateObject(Object *& ref);

通过这种方式,调用代码可以简单地传递指针变量(而不需要使用&来获取其地址),并且函数定义可以简单地分配给参数(而不需要使用*取消引用)。

答案 2 :(得分:0)

与示例代码等效的现代C ++将使用智能指针进行所有权,并使用迭代器访问数组元素:

#include <array>
#include <memory>

int main()
{
    // Define our types:
    using A_array = std::array<double, 4>;
    using A_iterator = A_array::iterator;

    // Make smart pointers to manage ownership for us:
    auto const A = std::make_unique<A_array>();
    auto const a = std::make_unique<std::array<A_iterator, 2>>();

    // Normally, we'd just put these in automatic storage, as
    // they are small, and don't outlive the function scope:
    // A_array A;
    // std::array<A_iterator, 2> a;)

    {
        // Populate a with iterators to A's elements
        auto target = A->begin();
        for (auto& element: *a) {
            element = target;
            target += 2;
        }
    }

    // No need for delete[] at end of function or at any other
    // return statement.
}