我正在阅读C++中的智能指针,并看到这个例子给出了如果使用普通指针,智能指针如何处理"悬空指针"问题.PS我知道auto_ptr被C++ 2011弃用了,但它仍然有unique_ptr或者它的一些等价物.
晃来晃去的指针.常规指针的常见缺陷是悬空指针:指向已删除对象的指针.以下代码(例如用于jsut)说明了这种情况:
MyClass* p(new MyClass);//Assume we have a MyClass definition available
MyClass* q = p;
delete p;
p->DoSomething();
p = NULL; // p is not dangling anymore
q->DoSomething(); // Don't.. q is still dangling!
Run Code Online (Sandbox Code Playgroud)
使用auto_ptr,这可以通过在复制时将其指针设置为NULL来解决(复制构造函数实现如下):
template <class T>
auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<T>& rhs)
{
if (this != &rhs) {
delete ptr;
ptr = rhs.ptr;
rhs.ptr = NULL;
}
return *this;
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我们使用auto_ptr具有相同的代码,如下所示:
auto_ptr<MyClass> p(new MyClass);
auto_ptr<MyClass> q = p;
delete p;
p->DoSomething();
p = NULL;
q->DoSomething();
Run Code Online (Sandbox Code Playgroud)
我得到了aqbove复制构造函数中的逻辑,但是如何使rhs.ptr = NULL有帮助.我的意思是如果稍后一个解引用此指针(上面的代码示例中的q),它将崩溃,因为它由智能指针复制构造函数使其为NULL.
如果它是一个正常的指针,我们会取消引用一个悬空指针,那会发生什么?一些未定义的行为可能.但是如何使用auto_ptr帮助
我在我的项目中使用了普通指针。我在内存方面遇到了一些问题,并更改了weak_ptr 的普通指针。我有错误:
错误:“->”的基操作数具有非指针类型“boost::weak_ptr”
为什么?我该怎么办?
我有一个像这样的库提供的课程:
template <typename T>
class TypedClass
{
public:
typedef typename boost::shared_ptr<TypedClass<T> > Ptr;
T m_data;
T* m_pointer_data;
};
Run Code Online (Sandbox Code Playgroud)
假设我愿意接受int和float在这个特定体系结构上总是相同的大小(和对齐),这似乎对我有用:
TypedClass<int>* int_object = new TypedClass<int>();
TypedClass<float>* float_object = reinterpret_cast<TypedClass<float>* >(int_object);
Run Code Online (Sandbox Code Playgroud)
现在我正在尝试使用boost shared_ptrs来实现相同的功能,并提出了这个:
TypedClass<int>::Ptr int_object = TypedClass<int>::Ptr(new TypedClass<int>());
void* int_object_void_pointer = reinterpret_cast<void*>(int_object.get());
TypedClass<float>::Ptr float_object(reinterpret_cast<TypedClass<float>*>(int_object_void_pointer));
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常,但这种共享指针的使用将导致对象被删除两次,我想避免.
需要注意的是,'TypedClass'是第三方库的一部分,并且该库使用共享指针来实现其所有内部功能,因此我需要这种形式的数据.我之前已经解决了从boost enable_shared_from_this继承的问题,但这不可能.
这是一种简单的技术,尝试将相同的对象重用于具有相同大小的数据类型,而无需使用新类型分配新对象.
建议欢迎.
可以将weak_ptr 与shared_ptr 一起使用。但我想知道是否可以创建一个引用同一个对象的 shared_ptr 和 unique_pointer 。如果是,必须遵循哪个规则?
嗨,我正在尝试使用智能指针实现一个简单的单链表,这是我到目前为止所拥有的,我选择使用 C++ 的 shared_ptr,但我读到 unique_ptr 更适合这种情况,但是,我不是真的知道如何遍历列表(即 currentNode = currentNode->next)以到达列表的末尾,以便使用 unique_ptr 插入元素。这是我到目前为止的代码:
template <typename T>
class LinkedList;
template <typename T>
class ListNode
{
public:
ListNode() : _data(T()) {}
explicit ListNode(const T& value) : _data(value) {}
friend class LinkedList < T > ;
private:
T _data;
shared_ptr<ListNode<T>> _next;
};
template <typename T>
class LinkedList
{
public:
void push_back(const T& value)
{
if (_root)
{
shared_ptr<ListNode<T>> currentNode(_root);
while (currentNode->_next != nullptr)
{
currentNode = currentNode->_next;
}
currentNode->_next = make_shared<ListNode<T>>(value);
}
else
{
// …Run Code Online (Sandbox Code Playgroud) 假设我有一个程序,我必须使用全局变量(某些类类型).
我希望能够使用智能指针,所以我不必担心删除它.
在一些文件中Common.hpp我有声明:
extern unique_ptr<CommandBuffer> globalCommandBuffer;
Run Code Online (Sandbox Code Playgroud)
在我的main.cpp中:
#include "Common.hpp"
int main(int argc, char* argv[]) {
globalCommandBuffer(new CommandBuffer());
}
Run Code Online (Sandbox Code Playgroud)
这会产生许多编译错误.显然我做错了.
我的问题是:
我有一个(例如)uint8_ts 的数组.
std::unique_ptr用于在内存中管理此对象的错误工具是什么?
例如,
std::unique_ptr<uint8_t> data(new uint8_t[100]);
Run Code Online (Sandbox Code Playgroud)
这会产生不确定的行为吗?
我想要一个智能指针对象来为我管理一些分配的内存.std::vector不理想,因为它是一个动态的对象.std::array也不好,因为在编译时不知道分配的大小.我无法使用[目前,2016-03-06]实验std::dynarray,因为Visual Studio 2013尚未提供.
不幸的是,我必须遵守VS2013,因为,规则.
我正在尝试更新一些C++代码,我想转向更现代的代码(c ++ 11),但我仍然需要使用一些较旧的编译器(符合c ++ 03)编译代码,因为支持的平台约束.
我知道在C++ 11编译器中不推荐使用std :: auto_ptr,但由于编译器支持较旧,我不能只用std :: unique_ptr替换它们.
有没有一个很好的做法来处理这个"旧的编译器支持,但是开始转向C++ 11"?
以下代码工作正常:
std::map<std::string,std::ofstream*> m_jsTabFilesMap;
m_jsTabFilesMap.insert({ listOfTabNames[i], new std::ofstream(jsFilename)});
Run Code Online (Sandbox Code Playgroud)
但是如果我用共享指针替换普通指针,那么插入函数会抛出没有函数的重载版本insert()存在.
std::map<std::string, std::shared_ptr<std::ofstream>> m_jsTabFilesMap;
Run Code Online (Sandbox Code Playgroud)
我该如何解决 ?是否与我使用new实例化对象的方式有关.
void f1(unique_ptr<A[]>& upA){
//some work...
//callee can mess up smart pointer many ways for caller
upA.reset();
//some work...
}
void f2(const unique_ptr<A[]>& upA){
//some work...
//compiler stops callee from ruining smart pointer many ways for caller
upA.reset();
//some work...
}
f1(upAArray);
f2(upAArray);
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,调用f1是危险的,因为被调用者可以通过重置智能指针,释放它等来搞乱智能指针等.调用f2是安全的,一切都很好.如果被调用者试图做坏事,编译器会抓住它.这样,当调用堆栈展开并且我们回到调用者时,智能指针就是声音.
重要的是,我不是问最好的智能指针传递方式(我意识到常规原始指针void f3(A*pAArray){}会没问题.我在问f2有什么问题?一般的建议是不要使用const引用unique_ptr作为参数,虽然我知道为什么这不是最优,我不明白为什么它比f1()更糟糕.
简而言之,具体而言,反对f2()的理由是什么?它做坏事吗?它似乎安然无恙(虽然肯定不是最佳的),我不明白它为何如此糟糕.
c++ ×10
smart-pointers ×10
c++11 ×6
shared-ptr ×2
unique-ptr ×2
boost ×1
c++03 ×1
c++14 ×1
casting ×1
linked-list ×1
pointers ×1