我有一系列工厂回归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中,这意味着我需要确保生成的对象在创建它们的同一个上下文(堆空间)中被销毁.所有权的转移(通常发生在另一个上下文中)必须从原始上下文中提供删除.但除了必须与指针一起提供/转换删除器之外,铸造问题应该是相同的.
在我最近评论的一段代码中,编译好了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)
编译结果:
所以问题是:哪个编译器在标准方面是正确的?标准是否要求这是一个无效的声明,一个有效的声明,或者这是不确定的?
加成
我们已经同意这些编译器中的一些,例如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:不是普遍可编辑的
如果我理解正确,a weak_ptr不会增加托管对象的引用计数,因此它不代表所有权.它只是让您访问一个对象,其生命周期由其他人管理.所以我真的不明白为什么一个weak_ptr不能用a构建unique_ptr,而只能用a 构建shared_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)
我的问题分为两部分:
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 …
我有类似于shared_ptr<Type> t(makeSomething(), mem_fun(&Type::deleteMe))
我现在需要调用需要指针的C样式函数Type.我怎样才能得到它shared_ptr?
我有一个返回智能指针的工厂.无论我使用什么智能指针,我都无法让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.
我正试图"现代化"一些现有的代码.
这很好用,但为了"现代化"我的代码,我认为我应该更改要定义的变量,"std::unique_ptr<Device> device_"并删除显式调用delete,这使得代码更安全,通常更好.
我的问题是这个 -
我可以调用.get来获取每个函数调用中的原始指针.但这看起来很丑陋,浪费了一些首先使用unique_ptr的原因.
或者我可以更改每个函数,以便不使用"Device*"类型的参数,而是使用"std :: unique_ptr&"类型的参数.哪个(对我来说)有点模糊了函数原型,并使它们难以阅读.
这是什么最佳做法?我错过了其他选择吗?
智能指针如何处理数组?例如,
void function(void)
{
std::unique_ptr<int> my_array(new int[5]);
}
Run Code Online (Sandbox Code Playgroud)
当my_array超出范围并被破坏时,整个整数数组是否会被重新声明?只回收了数组中的第一个元素吗?或者还有其他事情发生(例如未定义的行为)?
c++ ×10
smart-pointers ×10
unique-ptr ×5
c++11 ×4
boost ×2
shared-ptr ×2
casting ×1
clang++ ×1
g++ ×1
googlemock ×1
pointers ×1
unit-testing ×1
weak-ptr ×1