繁体   English   中英

在ac / c ++项目中使用指针指向和/或引用指向最有用的时间是什么?

[英]What was the most useful time you used a pointer-to-pointer and/or reference-to-pointer in a c/c++ project?

指针指向指针和指针指向一开始似乎过于复杂,特别是对于新手。 在您从事的ac / c ++项目中使用其中一个的最佳和最有用的原因是什么?

这可以帮助人们更好地理解指针以及如何有效地使用它们。

编辑:包括C和C ++

指向指针的指针非常常用作分配和返回缓冲区的参数,例如字符串:

void SetValue(char** buf)
{
    string s = "Hello, Ptr Ref";
    *buf = new char[s.length()+1];
    copy(s.begin(), s.end(), *buf);
    (*buf)[s.length()] = 0;
}


int main()
{
    char* buf = 0;
    SetValue(&buf);
    cout << buf;
    delete [] buf;
    return 0;
}

同样,除了传递指向要分配和修改的缓冲区的指针之外,您还可以传递对该缓冲区的引用。 这可以帮助向调用方阐明函数的语义,以使它们不执行调用SetValue(0);

void SetValue(char*& buf)
{
    string s = "Hello, Ptr Ref";
    buf = new char[s.length()+1];
    copy(s.begin(), s.end(), buf);
    buf[s.length()] = 0;
}


int main()
{
    char* buf = 0;
    SetValue(buf);
    cout << buf;
    delete [] buf;
    return 0;
}

但是,即使SetValue(char*&)的语义可能比SetValue(char**)版本更清晰,但仍有改进的空间。 谁拥有结果指针的问题浮现在脑海。

请记住,尽管这些示例是简单且人为设计的,但这样的实现比比皆是。 在许多情况下,您别无选择-例如,当调用诸如FormatMessage()之类的WINAPI函数并要求其分配缓冲区时。 但是在编写函数的其他许多情况下,还有其他方法可以为猫皮化。 可以说,更好的方法。 如:

string GimmeValue()
{
  return "Hello, String";
}

由于多种原因,这可能会更好。 从语义上说,按值返回值比使用指针到指针之类的outval更为清楚,因为所有权问题很容易解决。 通常最好避免在堆栈分配的变量可以正常工作的地方使用new运算符,因为这样可以避免由于多次delete缓冲区而导致潜在的内存泄漏或缺陷。

指针对指针? 动态分配的2D阵列!

我几乎记不起来上一次直接使用其中一个。 通常,它们对于执行诸如实现自己的容器类之类的操作很有用-例如,如果要在链表中分配节点,则节点之间有指针,并且如果要修改已传递的指针对于函数,您需要引用或指向该指针的指针。

当然,您也可以使用指向指针的指针来创建伪2D数组。 如果确实需要方形数组,则不是一个特别好的选择,但是如果您想要一个“参差不齐的数组”(例如,一个字符串数组,每个字符串的长度可能不同),则很有用。

在C语言中,指向指针的指针几乎是不可避免的,但是在C ++中,标准库已经具有容器类-例如,如果要在C语言中使用动态大小的字符串的动态数组,几乎唯一的选择是从char **开始,并动态分配作品。 在C ++中,您通常要使用std::vector<std::string>代替。 当/如果您决定实现自己的容器,您仍然会遇到它们,但是这种情况很少发生(至少您必须从原始指针等开始,而不是在现有容器之上构建)。

由于尚无人提及,因此它们可用作迭代器。

假设您有某种对象的列表。 您需要按特定的顺序遍历其中的一些。

因此,您将创建一个数组,其中包含指向您需要遍历的对象的指针,然后对该数组进行排序。

指向该数组的迭代器是指向指针的指针。

使用std::sort对其进行std::sort需要一对迭代器,这意味着它需要一对指向指针的指针。

然后使用std::for_each遍历它也需要一对迭代器。

这就是我上次使用指针指向的上下文。 (实际上,我有最后一层抽象层,所以最终得到了指向指针的指针,但这可能更不寻常了)

传递一个值数组,这些值表示用于地理处理的TIFF文件的内容。

好吧, char **argv和动态分配的二维锯齿状数组通常都非常有用。

每当您要允许被调用方更改指针(而不是指针指向的对象)时,对指针的引用就很有用。 例如,有人动态地提供内存:

void feedMeSeymour(void *&p, int size) {
    p = new char[size];
}

假设您要返回已分配的缓冲区-否则您可能需要重新分配传入的缓冲区。

您可以返回一个指向缓冲区的指针,也可以让调用者传入一个指针的地址(这样您就有一个指向指针的指针),然后将该指针设置为指向您的缓冲区。

COM-返回接口的任何方法都必须将指针传递给指向指针参数的指针。

我曾经在函数中使用char *** arg参数来更新就位的动态分配的类似argv的数组,并且还吓坏了同事们。

指向指针的指针也非常适合创建混合长度数组。 我认为它们通常被称为 刚性 锯齿阵列。 在减少嵌入式系统上的内存使用量之前,我曾使用过此方法。

模板化排序矢量的排序功能。 这是一个相当现实的示例:

template <typename T>
class Vector {
public:
    typedef bool SortFunc(const T& left, const T& right) ;
    void SetSort(SortFunc* pFunc){}
};


bool intSort(const int& left, const int& right)
{
    return true;
}

bool pintSort( int* const & left, int* const & right)
{
    return true;
}

//in main

Vector<int> intVec;
Vector<int*> pintVec;

intVec.SetSort(&intSort);
pintVec.SetSort(&pintSort);

考虑到我们可以将任何东西作为向量参数传递的事实,使用const引用作为排序函数参数相当合理。 什么是不理智的,虽然,正在抓紧研究如何串血腥的星号,连字号和consts以才达到一个常量引用非const整数的指针

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM