标签: smart-pointers

什么时候应该使用原始指针而不是智能指针?

在阅读完这个答案后,看起来最好尽可能使用智能指针,并将"普通"/原始指针的使用量降至最低.

真的吗?

c++ boost pointers smart-pointers

56
推荐指数
3
解决办法
3万
查看次数

"向下转换"unique_ptr <Base>到unique_ptr <Derived>

我有一系列工厂回归unique_ptr<Base>.引擎盖下,虽然,他们所提供的指针各种衍生类型,即unique_ptr<Derived>,unique_ptr<DerivedA>,unique_ptr<DerivedB>

鉴于DerivedA : Derived并且Derived : Base我们有:

unique_ptr<Base> DerivedAFactory() {
    return unique_ptr<Base>(new DerivedA);
}
Run Code Online (Sandbox Code Playgroud)

我需要做的是将指针从返回"转换" unique_ptr<Base>到某个派生级别(不一定是原始的内部级别).用伪代码说明:

unique_ptr<Derived> ptr = static_cast<unique_ptr<Derived>>(DerivedAFactory());
Run Code Online (Sandbox Code Playgroud)

我正在考虑通过从中释放对象unique_ptr,然后使用一个转换原始指针的函数并将其重新分配给另一个unique_ptr所需的风格(release在调用之前由调用者显式完成)来实现这一点:

unique_ptr<Derived> CastToDerived(Base* obj) {
    return unique_ptr<Derived>(static_cast<Derived*>(obj));
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,还是/会有什么时髦吗?


PS.还有一个复杂的问题是,有些工厂驻留在运行时动态加载的DLL中,这意味着我需要确保生成的对象在创建它们的同一个上下文(堆空间)中被销毁.所有权的转移(通常发生在另一个上下文中)必须从原始上下文中提供删除.但除了必须与指针一起提供/转换删除器之外,铸造问题应该是相同的.

c++ smart-pointers factory-pattern unique-ptr c++11

56
推荐指数
1
解决办法
2万
查看次数

从unique_ptr创建shared_ptr

在我最近评论的一段代码中,编译好了g++-4.6,我遇到了一个奇怪的尝试来创建一个std::shared_ptr来自std::unique_ptr:

std::unique_ptr<Foo> foo...
std::make_shared<Foo>(std::move(foo));
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎很奇怪.这应该是std::shared_ptr<Foo>(std::move(foo));afaik,虽然我对动作并不完全熟悉(而且我知道std::move只是演员,没有任何动静).

检查此SSC上的不同编译器(NUC*)E

#include <memory>

int main()
{
   std::unique_ptr<int> foo(new int);
   std::make_shared<int>(std::move(foo));
}
Run Code Online (Sandbox Code Playgroud)

编译结果:

  • g ++ - 4.4.7给出了编译错误
  • g ++ - 4.6.4编译没有任何错误
  • g ++ - 4.7.3给出了内部编译器错误
  • g ++ - 4.8.1给出了编译错误
  • clang ++ - 3.2.1编译没有任何错误

所以问题是:哪个编译器在标准方面是正确的?标准是否要求这是一个无效的声明,一个有效的声明,或者这是不确定的?

加成

我们已经同意这些编译器中的一些,例如clang ++和g ++ - 4.6.4,允许转换,而不应该.但是对于g ++ - 4.7.3(会产生内部编译器错误std::make_shared<Foo>(std::move(foo));),请正确拒绝int bar(std::move(foo));

由于这种巨大的行为差异,我将问题保持不变,尽管其中一部分将与减少相关int bar(std::move(foo));.


*)NUC:不是普遍可编辑的

c++ g++ smart-pointers c++11 clang++

50
推荐指数
3
解决办法
4万
查看次数

为什么不能从unique_ptr构造weak_ptr?

如果我理解正确,a weak_ptr不会增加托管对象的引用计数,因此它不代表所有权.它只是让您访问一个对象,其生命周期由其他人管理.所以我真的不明白为什么一个weak_ptr不能用a构建unique_ptr,而只能用a 构建shared_ptr.

有人能简单解释一下吗?

c++ smart-pointers shared-ptr weak-ptr unique-ptr

50
推荐指数
6
解决办法
2万
查看次数

对于像所有权语义这样的原始指针返回unique_ptr的不良做法?

我编写了一个静态工厂方法,它返回从另一个数据对象填充的新Foobar对象.我最近一直沉迷于所有权语义,我想知道我是否通过这种工厂方法返回一个正确的信息unique_ptr.

class Foobar {
public:
    static unique_ptr<Foobar> factory(DataObject data);
}
Run Code Online (Sandbox Code Playgroud)

我的目的是告诉客户端代码他们拥有指针.没有智能指针,我只会回来Foobar*.但是,我想强制删除这个内存以避免潜在的错误,所以这unique_ptr似乎是一个合适的解决方案.如果客户端想要延长指针的生命周期,他们只需在调用.release()后调用unique_ptr.

Foobar* myFoo = Foobar::factory(data).release();
Run Code Online (Sandbox Code Playgroud)

我的问题分为两部分:

  1. 这种方法是否传达了正确的所有权语义?
  2. 返回unique_ptr而不是原始指针这是一个"坏习惯" 吗?

c++ smart-pointers ownership-semantics unique-ptr

49
推荐指数
3
解决办法
2万
查看次数

unique_ptr的动态转换

正如Boost中的情况一样,C++ 11提供了一些用于转换的函数shared_ptr:

std::static_pointer_cast
std::dynamic_pointer_cast
std::const_pointer_cast
Run Code Online (Sandbox Code Playgroud)

但是,我想知道为什么没有等效功能unique_ptr.

考虑以下简单示例:

class A { virtual ~A(); ... }
class B : public A { ... }

unique_ptr<A> pA(new B(...));

unique_ptr<A> qA = std::move(pA); // This is legal since there is no casting
unique_ptr<B> pB = std::move(pA); // This is not legal

// I would like to do something like:
// (Of course, it is not valid, but that would be the idea)
unique_ptr<B> pB = std::move(std::dynamic_pointer_cast<B>(pA));
Run Code Online (Sandbox Code Playgroud)

是否有任何理由不鼓励这种使用模式,因此,shared_ptr没有提供与现有模式相同的功能unique_ptr …

c++ casting smart-pointers unique-ptr c++11

49
推荐指数
4
解决办法
3万
查看次数

从shared_ptr获得正常的ptr?

我有类似于shared_ptr<Type> t(makeSomething(), mem_fun(&Type::deleteMe)) 我现在需要调用需要指针的C样式函数Type.我怎样才能得到它shared_ptr

c++ boost smart-pointers shared-ptr

47
推荐指数
2
解决办法
7万
查看次数

谷歌可以用智能指针返回类型模拟一个方法吗?

我有一个返回智能指针的工厂.无论我使用什么智能指针,我都无法让Google Mock嘲笑工厂方法.

模拟对象是纯抽象接口的实现,其中所有方法都是虚拟的.我有一个原型:

MOCK_METHOD0(Create, std::unique_ptr<IMyObjectThing>());
Run Code Online (Sandbox Code Playgroud)

我得到:

"...gmock/gmock-spec-builders.h(1314): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'"
Run Code Online (Sandbox Code Playgroud)

定义了智能指针中指向的类型.

我得到它试图访问一个声明私有的构造函数,但我不明白为什么.当这是一个std :: auto_ptr时,错误说没有复制构造函数,这让我很困惑.

无论如何,有没有办法模拟一个返回智能指针的方法?或者有更好的方法来建造工厂吗?我唯一的决心是返回一个原始指针(blech ......)?

我的环境是Visual Studio 2010 Ultimate和Windows 7.我没有使用CLI.

c++ unit-testing smart-pointers googlemock

46
推荐指数
3
解决办法
2万
查看次数

将unique_ptr传递给函数

我正试图"现代化"一些现有的代码.

  • 我有一个类,当前有一个成员变量"Device*device_".
  • 它使用new在一些初始化代码中创建一个实例,并在destructory中有一个"delete device_".
  • 此类的成员函数调用许多其他函数,这些函数将Device*作为参数.

这很好用,但为了"现代化"我的代码,我认为我应该更改要定义的变量,"std::unique_ptr<Device> device_"并删除显式调用delete,这使得代码更安全,通常更好.

我的问题是这个 -

  • 那么我应该如何将device _变量传递给需要它作为参数的所有函数?

我可以调用.get来获取每个函数调用中的原始指针.但这看起来很丑陋,浪费了一些首先使用unique_ptr的原因.

或者我可以更改每个函数,以便不使用"Device*"类型的参数,而是使用"std :: unique_ptr&"类型的参数.哪个(对我来说)有点模糊了函数原型,并使它们难以阅读.

这是什么最佳做法?我错过了其他选择吗?

c++ smart-pointers unique-ptr

46
推荐指数
3
解决办法
3万
查看次数

智能指针和数组

智能指针如何处理数组?例如,

void function(void)
{
    std::unique_ptr<int> my_array(new int[5]);
}
Run Code Online (Sandbox Code Playgroud)

my_array超出范围并被破坏时,整个整数数组是否会被重新声明?只回收了数组中的第一个元素吗?或者还有其他事情发生(例如未定义的行为)?

c++ smart-pointers c++11

44
推荐指数
2
解决办法
3万
查看次数