我是一个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++代码替换它?
一些重要的清晰度:你被建议的是不使用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)
| 归档时间: |
|
| 查看次数: |
216 次 |
| 最近记录: |