取消引用指针以获取引用是错误的吗?

Mr.*_*Boy 31 c++ pointers stl reference

我更喜欢在任何地方使用引用,但是当你使用STL容器时,你必须使用指针,除非你真的想按值传递复杂的类型.我觉得很难转换回参考,这似乎是错误的.

是吗?

澄清...

MyType *pObj = ...
MyType &obj = *pObj;
Run Code Online (Sandbox Code Playgroud)

这不是'脏',因为你可以(即使只是在理论上,因为你先检查它)取消引用一个NULL指针?

编辑:哦,你不知道对象是否是动态创建的.

Mer*_*ham 18

在尝试将指针转换为引用之前确保指针不为NULL,并且只要引用(或保持分配,引用堆),对象将保留在作用域中,并且您将没事,道德干净:)

  • @Billy:重新阅读他们所写的内容.他们使用的是STL容器,但是他们不希望将值存储在容器中,因此需要在插入时使用复制构造函数.他们想要一个(智能)指针的容器,指向可能动态分配的值,或者可能不是(例如静态数组). (3认同)
  • 动态分配的对象如何在范围内? (2认同)
  • @Billy:我们不知道它们是动态分配的,只是我们指的是它们. (2认同)

Ste*_*sop 13

使用解除引用的指针初始化引用绝对没问题,无论如何都没有错.如果p是指针,并且如果解除引用它是有效的(例如,它不是null),那么*p它是指向的对象.您可以绑定对该对象的引用,就像绑定对任何对象的引用一样.显然,您必须确保引用不会超过对象(就像任何引用一样).

例如,假设我传递了一个指向对象数组的指针.它也可以是迭代器对,或对象的向量,或对象的向量map,但为了简单起见,我将使用数组.每个对象都有一个函数order,返回一个整数.我bar按照增加的order值顺序在每个对象上调用一次函数:

void bar(Foo &f) {
    // does something
}

bool by_order(Foo *lhs, Foo *rhs) {
    return lhs->order() < rhs->order();
}

void call_bar_in_order(Foo *array, int count) {
    std::vector<Foo*> vec(count);  // vector of pointers
    for (int i = 0; i < count; ++i) vec[i] = &(array[i]);
    std::sort(vec.begin(), vec.end(), by_order);
    for (int i = 0; i < count; ++i) bar(*vec[i]); 
}
Run Code Online (Sandbox Code Playgroud)

我的示例初始化的引用是函数参数而不是直接变量,但我可以有效地完成:

for (int i = 0; i < count; ++i) {
    Foo &f = *vec[i];
    bar(f);
}
Run Code Online (Sandbox Code Playgroud)

显然,vector<Foo>这是不正确的,因为那时我会按顺序调用每个对象bar副本,而不是按顺序调用每个对象.bar采用非const引用,所以除了性能或其他任何东西,如果bar修改输入显然是错误的.

智能指针或提升指针向量的向量也是错误的,因为我不拥有数组中的对象,当然也不能释放它们.也可能不允许对原始数组进行排序,或者如果它map不是数组则不可能.


Bil*_*eal 5

不。你还能如何实现operator=?您必须取消引用this才能返回对自己的引用。

请注意,我仍然会按值将项目存储在 STL 容器中——除非您的对象很大,否则堆分配的开销将意味着您使用更多的存储空间,并且效率低于您只是按值存储项目。

  • 这也意味着你的班级必须有一个空的/默认的构造函数。这可能意味着编写额外的代码只是为了允许您将它们放入容器中,当处于此状态的对象无效时。只是看起来很乱。 (2认同)