如果p->m仅仅是语法糖是不是有意义(*p).m?基本上,operator->我写过的每一个都可以实现如下:
Foo::Foo* operator->()
{
return &**this;
}
Run Code Online (Sandbox Code Playgroud)
在任何情况下,我想要p->m的意思是什么(*p).m?
从他的STL书中读到Jossutis对auto_ptr的解释之后,我得到了一个强烈的印象,即我会尝试使用它的任何任务100%失败,因为很多auto_ptr的陷阱之一.
我的问题是:有没有任何真正的生活任务,其中auto_ptr真的很有用,并且适合那里吗?
我的问题涉及shared_ptrGCC 4.7.2中的赋值运算符模板的实现,我怀疑它包含一个bug.
PREMISE 1:C++ 11标准
这是我正在谈论的赋值运算符模板的签名:
template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
Run Code Online (Sandbox Code Playgroud)
从C++ 11标准(20.7.2.2.3):
"相当于 shared_ptr(r).swap(*this)."
换句话说,赋值运算符模板是根据构造函数模板定义的.构造函数模板的签名如下:
template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
Run Code Online (Sandbox Code Playgroud)
从C++ 11标准(20.7.2.2.1):
"要求:[...]构造函数不应参与重载决策,除非Y*可隐式转换为T*."
PREMISE 2:GCC 4.7.2的实施:
现在GCC 4.7.2的构造函数模板的实现对我来说似乎是正确的(std::__shared_ptr是基类std::shared_ptr):
template<typename _Tp1, typename =
typename std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
__shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
:
_M_ptr(__r._M_ptr),
_M_refcount()
{
_M_refcount._M_swap(__r._M_refcount);
__r._M_ptr = 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,GCC 4.7.2的赋值运算符模板的实现如下:
template<typename _Tp1>
__shared_ptr& operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
{
_M_ptr = __r._M_ptr;
_M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw …Run Code Online (Sandbox Code Playgroud) 我正在尝试Subject从观察者模式中编写一个安全类.我想知道使用weak_ptr是否是以下列方式存储IObserver实例的最佳方式:
IObserver被释放后无法使用实例.Subject类不抱上IObserver应free'd引用(流逝的听众的问题).Subject类必须是线程安全的.不幸的是,我们的编码标准说我们不允许使用boost.我想我以前的生活中是一个坏人.幸运的是,我被允许使用C++ 11(Visual Studio 2012附带的内容).
这是一个示例Observer类.
// Observer interface that supports notify() method
class IObserver
{
public:
virtual void notify() const = 0;
virtual ~IObserver() {}
};
// Concrete observer implementation that prints a message
class Observer : public IObserver
{
public:
Observer( const std::string& message) : m_message( message ){}
void notify() const {
printf( "%s\r\n", m_message.c_str() …Run Code Online (Sandbox Code Playgroud) 让我通过一个例子提出我的问题.
#include <memory>
std::unique_ptr<int> get_it() {
auto p = new int;
return p;
}
int main() {
auto up ( get_it() );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
无法编译时出现以下错误:
a.cpp:5:9: error: could not convert ‘p’ from ‘int*’ to ‘std::unique_ptr<int>’
return p;
^
Run Code Online (Sandbox Code Playgroud)
为什么没有从原始指针自动转换为唯一的指针?我应该做什么呢?
动机:我理解使用智能指针清除所有权应该是一种好习惯; 我从某个地方得到一个指针(我拥有),就像int*在这种情况下一样,我(想想我)想要它unique_ptr.
如果您正在考虑评论或添加您自己的答案,请在提案N4029中解决Herbert Sutter关于此问题的论点.
所以在使用时shared_ptr<Type>你可以写:
shared_ptr<Type> var(new Type());
Run Code Online (Sandbox Code Playgroud)
我想知道为什么他们不允许更简单和更好(imo):
shared_ptr<Type> var = new Type();
Run Code Online (Sandbox Code Playgroud)
而不是要实现这样的功能,您需要使用.reset():
shared_ptr<Type> var;
var.reset(new Type());
Run Code Online (Sandbox Code Playgroud)
我习惯于OpenCV Ptr类,它是一个智能指针,允许直接赋值,一切正常
为什么以及何时需要提供自己的删除器?关键字不delete足够吗?
如果您使用智能指针来管理分配的内存以外的资源
new,请记住传递删除器.
正如在评论中被问到的那样,我不清楚引用的文本和示例的原因是我在想某些东西是错误的,这是因为我一直在考虑智能指针只是为了动态内存管理而发明的.所以这个例子使用智能指针管理非动态内存让我感到困惑.
老人的一个很好的解释:
智能指针根本不关心动态内存本身.它只是一种在需要时跟踪某些东西的方法,并在它超出范围时销毁它.提到文件句柄,网络连接等的要点是指出它们不是动态内存,但智能指针可以管理它们就好了.
C++ Primer 5th采用伪网络连接(不定义析构函数)来说明.
坏:
struct destination; // represents what we are connecting to
struct connection; // information needed to use the connection
connection connect(destination*); // open the connection
void disconnect(connection); // close the given connection
void f(destination &d /* other parameters */)
{
// get a connection; must remember to close it when done
connection c = connect(&d);
// use the connection
// if we …Run Code Online (Sandbox Code Playgroud) 由于我的noob声誉,我无法回复此主题,特别是接受的答案:
我从未使用过boost :: intrusive智能指针,但如果你使用shared_ptr智能指针,你可以使用weak_ptr对象作为缓存.
当系统决定释放内存时,那些weak_ptr指针不算作引用,但只要该对象尚未被删除,它就可用于检索shared_ptr.
这当然是一个直观的想法,但是,C++标准不支持weak_ptrs的比较,因此它不能用作关联容器的键.这可以通过为weak_ptrs实现比较运算符来规避:
template<class Ty1, class Ty2>
bool operator<(
const weak_ptr<Ty1>& _Left,
const weak_ptr<Ty2>& _Right
);
Run Code Online (Sandbox Code Playgroud)
这个解决方案的问题是
(1)比较运算符必须获得每次比较的所有权(即从weak_ptr refs创建shared_ptrs)
(2)当管理资源的最后一个shared_ptr被破坏时,weak_ptr不会从缓存中删除,但是过期的weak_ptr会保留在缓存中.
对于(2),我们可以提供自定义析构函数(DeleteThread),但是,这将需要再次从要删除的T*创建weak_ptr,然后可以使用它从缓存中擦除weak_ptr.
我的问题是,如果有更好的方法使用智能指针缓存(我使用VC100编译器,没有提升),或者我根本没有得到它?
干杯,丹尼尔
我有一个类A,其字段类型为std::unique_ptr:
class A
{
public:
std::unique_ptr pointer;
// class body
};
Run Code Online (Sandbox Code Playgroud)
在代码中的某个地方,我使用很少的std::shared_ptrs指向同一个对象.现在我想要实现的是std::unique_ptr在我的班级中将所有权转移到这个,这样如果所有的shared_ptrs都将被销毁,只要这个unique_ptr将保持活着,我的对象将保持活着.
我的问题是 - 是否有可能将所有权转移std::shared_ptr到std::unique_ptr,如果是,我该怎么做?
我最近遇到了将指针指向成员应用于迭代器指定的对象的需要.我尝试过自然语法:
ite->*ptr = 42;
Run Code Online (Sandbox Code Playgroud)
令我沮丧的是,它没有编译.迭代器不会过载operator->*,但更令人惊讶的是智能指针也不会.我需要诉诸以下笨拙:
(*ite).*ptr = 42;
Run Code Online (Sandbox Code Playgroud)
试验(参见下面的实例)已经表明,对于自定义类,对于指向成员的指针和指向成员函数的指针,这样的语法似乎是可以实现的,至少从C++ 14开始.
因此:
operator->*,还是仅仅是一种疏忽?operator->*在定义类似指针的类时,我应该重载,还是同样的理由适用于我?实例 - 什么是编译,什么不编译,以及自定义类的概念验证.
c++ ×10
smart-pointers ×10
c++11 ×4
shared-ptr ×3
pointers ×2
stl ×2
auto-ptr ×1
c++14 ×1
caching ×1
explicit ×1
gcc ×1
iterator ×1
std ×1
unique-ptr ×1
weak-ptr ×1