只想对设计问题提出意见.如果你有一个C++类而不是拥有其他对象,你会使用智能指针来实现吗?
class Example {
public:
// ...
private:
boost::scoped_ptr<Owned> data;
};
Run Code Online (Sandbox Code Playgroud)
"拥有"对象不能按值存储,因为它可能会在对象的生命周期内发生变化.
我的观点是,一方面,你明确表示对象是拥有的并确保删除它,但另一方面,你可以很容易地只有一个常规指针并在析构函数中删除它.这有点矫枉过正吗?
跟进:只是想感谢您的所有答案.感谢关于auto_ptr的抬头在复制整个对象时使用NULL指针留下另一个对象,我已经广泛使用了auto_ptr但是还没想到.除非我有充分的理由,否则基本上我的所有类都是boost :: noncopyable,所以没有什么可担心的.还要感谢有关异常中内存泄漏的信息,这也是很好的.我尽量不编写可能导致构造函数中的异常的东西 - 有更好的方法可以做到这一点 - 所以这应该不是问题.
我只是有另一个问题.当我问这个问题时,我想知道是否有人真的这样做了,你们似乎都提到理论上这是一个好主意,但没有人说他们真的这样做了.这让我感到惊讶!当然,一个拥有指向另一个对象的对象并不是一个新想法,我希望你们在某个时刻之前都会做到这一点.这是怎么回事?
考虑:
delete new std :: string [2];
delete [] new std :: string;
Run Code Online (Sandbox Code Playgroud)
每个人都知道第一个是错误.如果第二个不是错误,我们就不需要两个不同的运算符.
现在考虑:
std :: unique_ptr <int> x (new int [2]);
std :: unique_ptr <int> y (new int);
Run Code Online (Sandbox Code Playgroud)
是否x知道使用delete[]而不是 delete?
背景:当我认为指针的数组类型限定将是一个方便的语言功能时,这个问题浮现在我脑海中.
int *[] foo = new int [2]; // OK
int * bar = new int; // OK
delete [] foo; // OK
delete bar; // OK
foo = new int; // Compile error
bar = new int[2]; // Compile error
delete foo; …Run Code Online (Sandbox Code Playgroud) 在C++中我们可以这样做:
struct Base
{
virtual Base* Clone() const { ... }
virtual ~Base(){}
};
struct Derived : Base
{
virtual Derived* Clone() const {...} //overrides Base::Clone
};
Run Code Online (Sandbox Code Playgroud)
但是,以下内容不会做同样的伎俩:
struct Base
{
virtual shared_ptr<Base> Clone() const { ... }
virtual ~Base(){}
};
struct Derived : Base
{
virtual shared_ptr<Derived> Clone() const {...} //hides Base::Clone
};
Run Code Online (Sandbox Code Playgroud)
在此示例中Derived::Clone 隐藏 Base::Clone而不是覆盖它,因为标准表示重写成员的返回类型可能仅从引用(或指针)更改为基础到引用(或指针).这有什么聪明的解决方法吗?当然有人可能认为Clone函数应该返回一个普通的指针,但是现在让我们忘记它 - 这只是一个例证.我正在寻找一种方法来启用虚拟功能的返回类型从智能指针更改Base为智能指针Derived.
提前致谢!
更新:感谢 Iammilind,我的第二个例子确实无法编译
A.hpp:
class A {
private:
std::unique_ptr<std::ifstream> file;
public:
A(std::string filename);
};
Run Code Online (Sandbox Code Playgroud)
A.cpp:
A::A(std::string filename) {
this->file(new std::ifstream(filename.c_str()));
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误被抛出:
A.cpp:7:43: error: no match for call to ‘(std::unique_ptr<std::basic_ifstream<char> >) (std::ifstream*)’
Run Code Online (Sandbox Code Playgroud)
有没有人知道为什么会这样?我已经尝试了很多不同的方法让它工作,但无济于事.
我有简单的基础和派生类,我想要两个shared_from_this().
这个简单的方案:
class foo : public enable_shared_from_this<foo> {
void foo_do_it()
{
cout<<"foo::do_it\n";
}
public:
virtual function<void()> get_callback()
{
return boost::bind(&foo::foo_do_it,shared_from_this());
}
virtual ~foo() {};
};
class bar1 : public foo , public enable_shared_from_this<bar1> {
using enable_shared_from_this<bar1>::shared_from_this;
void bar1_do_it()
{
cout<<"foo::do_it\n";
}
public:
virtual function<void()> get_callback()
{
return boost::bind(&bar1::bar1_do_it,shared_from_this());
}
};
Run Code Online (Sandbox Code Playgroud)
导致tr1::bad_weak_ptr以下代码中的异常:
shared_ptr<foo> ptr(shared_ptr<foo>(new bar1));
function<void()> f=ptr->get_callback();
f();
Run Code Online (Sandbox Code Playgroud)
所以在"谷歌搜索"之后我找到了以下解决方案:
class bar2 : public foo {
void bar2_do_it()
{
cout<<"foo::do_it\n";
}
shared_ptr<bar2> shared_from_this()
{
return boost::static_pointer_cast<bar2>(foo::shared_from_this());
}
public: …Run Code Online (Sandbox Code Playgroud) 返回智能指针时的最佳做法是什么,例如boost :: shared_ptr?我应该通过标准返回智能指针,还是底层的原始指针?我来自C#所以我倾向于总是返回智能指针,因为它感觉正确.像这样(跳过const-correctness更短的代码):
class X
{
public:
boost::shared_ptr<Y> getInternal() {return m_internal;}
private:
boost::shared_ptr<Y> m_internal;
}
Run Code Online (Sandbox Code Playgroud)
但是我看到一些有经验的编码器返回原始指针,并将原始指针放在向量中.做正确的方法是什么?
a的std::unique_ptr具体用途是什么,何时以及如何最好地使用?
我发现:
我已经知道了:
std::unique_ptr 是用C++ 11开发的替代品 std::auto_ptrstd::unique_ptr没有引用计数和它所指向的"拥有"对象std::unique_ptrstd::unique_ptr就是结构我想知道的是:
std::unique_ptr更好的(除了唯一性)别的std::unique_ptr利于std::shared_ptr在几乎所有情况下都能满足动态内存管理的需要,为什么我可以处理一std::unique_ptr件事(同样,我有一个问题.我们可以直接获得共享指针指向的对象吗?或者我们应该通过get()调用获取底层RAW指针然后访问相应的对象?
我最近开始将大量现有的C++应用程序代码移植到C++ 11,现在我转换为新的智能指针std :: unique_ptr和std :: shared_ptr,我有一个关于自定义删除的具体问题.我想添加一个lambda记录器来查看我的删除被调用的位置但是我无法获得要编译的数组特化版本.建议将非常感谢.
我已经白白被搜索用于阵列专业化一个定制删除的一个例子的unique_ptr为VC++ 10或GCC 4.5.2+.我想在lambda中调用删除器时打印一条日志消息 - 主要是为了确保我认为超出范围的所有指针都这样做.这可能是专业化的阵列版本吗?我可以使用非数组版本,如果我将外部结构"MyArrayDeleter"作为第二个参数传递,我也可以使用数组特化.还有一件事,是否有可能删除丑陋的std :: function,因为我认为我可以让lambda签名数字出来.
struct MySimpleDeleter {
void operator()(int* ptr) const {
printf("Deleting int pointer!\n");
delete ptr;
}
};
struct MyArrayDeleter {
void operator()(int* ptr) const {
printf("Deleting Array[]!\n");
delete [] ptr;
}
};
{
// example 1 - calls MySimpleDeleter where delete simple pointer is called
std::unique_ptr<int, MySimpleDeleter> ptr1(new int(5));
// example 2 - correctly calls MyArrayDeleter where …Run Code Online (Sandbox Code Playgroud) 这是一个智能指针:std::shared_ptr<char> p(new char[size])表示填充原始二进制文件内容的数组.在整个数组从文件复制到RAM之后(并且仅在之后),我可以解析它,在此期间我检索一些头信息(几个第一个dwords).然后是实际数据.
在没有提供更多上下文的情况下,将所提到的共享指针设置为实际数据开头的新地址非常方便.该地址仍处于已分配的内存中.但如何设置而不失去它?
一个问题是(是/否):是否可以设置p偏移主流指针,而无需调用数据删除?
c++ ×10
smart-pointers ×10
c++11 ×3
shared-ptr ×3
unique-ptr ×3
boost ×2
ifstream ×1
lambda ×1
oop ×1
return-type ×1
shared ×1