我有对象在其构造函数中创建其他子对象,传递'this',以便子进程可以将指针保存回其父对象.我在编程中广泛使用boost :: shared_ptr作为std :: auto_ptr或原始指针的更安全的替代品.因此,孩子将拥有诸如的代码shared_ptr<Parent>,并且boost提供shared_from_this()父母可以给孩子的方法.
我的问题是shared_from_this()不能在构造函数中使用,这不是真正的犯罪,因为"this"不应该在构造函数中使用,除非你知道你正在做什么并且不介意限制.
Google的C++样式指南指出构造函数应该只将成员变量设置为其初始值.任何复杂的初始化都应该采用显式的Init()方法.这解决了"这个构造函数"问题以及其他一些问题.
困扰我的是,现在使用代码的人必须记住每次构造一个对象时都调用Init().我可以想到强制执行此操作的唯一方法是通过断言已经在每个成员函数的顶部调用了Init(),但这样编写繁琐且执行起来很麻烦.
那边有什么习惯用法可以解决这个问题吗?
我有一个宠物项目,我用它来试验C++ 11的新功能.虽然我有C的经验,但我对C++还不熟悉.为了训练自己进入最佳实践,(除了阅读很多),我已经启用了一些严格的编译器参数(使用GCC 4.4.1):
-std=c++0x -Werror -Wall -Winline -Weffc++ -pedantic-errors
Run Code Online (Sandbox Code Playgroud)
这对我来说很好.到现在为止,我已经能够解决所有障碍.但是,我有需要enable_shared_from_this,这给我带来了问题.编译我的代码时可能会收到以下警告(在我的情况下是错误的)(可能由触发器引发-Weffc++):
base class ‘class std::enable_shared_from_this<Package>’ has a non-virtual destructor
Run Code Online (Sandbox Code Playgroud)
所以基本上,我对这个实现有点疑虑enable_shared_from_this,因为:
enable_shared_from_this.但我正在寻找解决这个问题的方法,所以我的问题是,是否有正确的方法来解决这个问题?并且:我认为这个析构函数是假的,或者它有真正的目的吗?
在c ++ 0x中,shared_ptr将从tr1移动到std.那么要包括哪个标题来获取它?
我正在使用g ++ 4.5(ubuntu 10.10)
我正在编写侵入式共享指针,我正在使用C++ 11 <atomic>工具作为参考计数器.以下是我的代码的相关片段:
//...
mutable std::atomic<unsigned> count;
//...
void
SharedObject::addReference() const
{
std::atomic_fetch_add_explicit (&count, 1u,
std::memory_order_consume);
}
void
SharedObject::removeReference() const
{
bool destroy;
destroy = std::atomic_fetch_sub_explicit (&count, 1u,
std::memory_order_consume) == 1;
if (destroy)
delete this;
}
Run Code Online (Sandbox Code Playgroud)
我已经开始memory_order_acquire和memory_order_release第一次,但后来我说服自己memory_order_consume应该足够好.在进一步审议后,在我看来,即使memory_order_relaxed应该工作.
现在,问题是我是否可以memory_order_consume用于操作或者我可以使用较弱的订单(memory_order_relaxed)还是应该使用更严格的订购?
与使用原始指针的类似(但不限于)某些高级技术相比,每个智能指针的等效用途是什么?
我的理解很少,但我可以收集到:
std::shared_ptr::reset底层时deallocator.std::shared_ptr不增加引用计数的子类型,当其父级std::shared_ptr不再存在时无效.可能会返回无效的引用.使用前请务必检查.RAW指针等效示例
引用计数,缓存实现: std::map<std::string, std::pair<long, BITMAP*> > _cache;
拥有所有权的单身人士:
class Keyboard {
public:
//...
static Keyboard* CreateKeyboard();
~Keyboard();
//...
private:
//...
Keyboard();
static Keyboard* _instance;
//...
};
Run Code Online (Sandbox Code Playgroud)
聚合容器,无所有权:空间分区图和树,迭代容器等.
复合容器,所有权:大型对象.
- 编辑 -
在我工作的时候,我遇到了一个有趣的案例,DeadMG指出智能指针应该被用作简单的抽象来处理资源管理; 那些在声明点无法在堆上创建但必须在以后创建的文件范围对象呢?
如何将指向const对象的shared_ptr转换为指向非const对象的shared_ptr.我正在尝试执行以下操作:
boost::shared_ptr<const A> Ckk(new A(4));
boost::shared_ptr<A> kk=const_cast< boost::shared_ptr<A> > Ckk;
Run Code Online (Sandbox Code Playgroud)
但它不起作用.
我对使用的最佳实践几乎没有疑问shared_ptr.
问题1
复制shared_ptr便宜吗?或者我是否需要将其作为参考传递给我自己的帮助函数并返回值?就像是,
void init_fields(boost::shared_ptr<foo>& /*p_foo*/);
void init_other_fields(boost::shared_ptr<foo>& /*p_foo*/);
boost::shared_ptr<foo> create_foo()
{
boost::shared_ptr<foo> p_foo(new foo);
init_fields(p_foo);
init_other_fields(p_foo);
}
Run Code Online (Sandbox Code Playgroud)
问题2
我应该boost::make_shared用来构建一个shared_ptr吗?如果是,它提供了哪些优势?make_shared当T没有无参数构造函数时,我们如何使用?
问题3
怎么用const foo*?我找到了两种方法来做到这一点.
void take_const_foo(const foo* pfoo)
{
}
int main()
{
boost::shared_ptr<foo> pfoo(new foo);
take_const_foo(pfoo.get());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
要么
typedef boost::shared_ptr<foo> p_foo;
typedef const boost::shared_ptr<const foo> const_p_foo;
void take_const_foo(const_p_foo pfoo)
{
}
int main()
{
boost::shared_ptr<foo> pfoo(new foo);
take_const_foo(pfoo);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
问题4
我怎样才能返回,检查NULL …
考虑以下代码:
#include <memory>
#include <iostream>
class SomeClass {
public:
SomeClass() {
std::cout << "SomeClass()" << std::endl;
}
~SomeClass() {
std::cout << "~SomeClass()" << std::endl;
}
void* operator new(std::size_t size) {
std::cout << "Custom new" << std::endl;
return ::operator new(size);
}
void operator delete(void* ptr, std::size_t size) {
std::cout << "Custom delete" << std::endl;
::operator delete(ptr);
}
};
int main() {
std::shared_ptr<SomeClass> ptr1(new SomeClass);
std::cout << std::endl << "Another one..." << std::endl << std::endl;
std::shared_ptr<SomeClass> ptr2(std::make_shared<SomeClass>());
std::cout << std::endl …Run Code Online (Sandbox Code Playgroud) 我正在尝试复制自定义类的对象Event.我有一个指向我从其分配中获得的对象的共享指针:
std::shared_ptr<Event> e = std::make_shared<Event>();
Run Code Online (Sandbox Code Playgroud)
为了获得e(不仅仅是指针的副本)的真实副本,我尝试过:
std::shared_ptr<Event> o = std::make_shared<Event>(*e);
Run Code Online (Sandbox Code Playgroud)
但我不确定这是否是正确的方式,因为如果我删除e它也会删除o...
顺便说一句,我还没有定义一个拷贝构造函数,Event::Event(const Event &orig)但在我的理解中,这并不是必需的,因为编译器提供了一个默认的拷贝构造函数.事件类只包含变量而没有其他指针.
感谢std::make_shared,我想知道,std::shared_ptr带有原始指针的构造函数是否具有任何值,除非与传统/库代码接口时,例如存储工厂的输出时.
shared_ptr<T>::reset(T*)?关于代码检查:我知道与遗留/库代码的接口很常见,因此自动代码检查可能会有问题,但在目前为止我遇到的大多数情况下,我宁愿使用一个unique_ptr而且我也不是在谈论弹出的编译器警告-Wall,而不是代码审查期间静态代码分析的规则.
我的动机:
相对容易说"不要使用std::shared_ptr<T>(new T(...)),总是喜欢std::make_shared<T>(...)"(我认为这是正确的建议吗?).但是我想知道它是不是一般的设计气味,如果必须shared_ptr从原始指针创建一个,甚至 - 或者特别是 - 如果对象不是仅仅通过创建new,因为该对象应该被创建为首先是"共享"或"独特"的对象.
shared-ptr ×10
c++ ×9
c++11 ×5
boost ×3
atomic ×1
auto-ptr ×1
constructor ×1
gcc ×1
header ×1
make-shared ×1
unique-ptr ×1
weak-ptr ×1