C++ C++;11智能指针用例
假设我正在开发一个小型电影数据库。用python之类的动态语言编写:C++ C++;11智能指针用例,c++,c++11,smart-pointers,C++,C++11,Smart Pointers,假设我正在开发一个小型电影数据库。用python之类的动态语言编写: db = ConnectionFactory.get_connection(db_name) # (1) Create database connection model = MovieModel(db) # (2) object-to-relational mapper star_wars = Movie("Star Wars", ...) model.store(star_w
db = ConnectionFactory.get_connection(db_name) # (1) Create database connection
model = MovieModel(db) # (2) object-to-relational mapper
star_wars = Movie("Star Wars", ...)
model.store(star_wars) # (3) Save object
et = model.fetch("E.T.") # (4) Retrieve one object
movies = model.fetch_all() # (5) Retrieve all objects
当将此转换为C++时,问题就出现了:如何通过对象传递:值、引用、普通指针或少数智能指针之一。 第1行合并了一个抽象工厂,它返回某个基类的子类,所以这里需要返回一个指针。问题是,应该返回什么类型的指针
std::unique_ptr
似乎很适合
在第2行中,构建了MovieModel,它将数据库连接作为参数并存储起来以备将来使用。由于一个连接可以在一个或多个模型之间共享,我认为数据库连接应该作为std::shared_ptr
传递和存储。但是,我应该将ConnectionFactory
创建的std::unique\u ptr
转换为shared\u ptr
还是修改ConnectionFactory
以返回shared\u ptr
在第3行中,存储在数据库中的对象。由于Movie
是一个简单的“数据”类,所以应该通过值传递,或者更好地通过常量引用传递。这很简单,但在第4行中检索到另一个对象。由于Movie
具有“值”语义,按值返回似乎很自然。但当找不到特定的电影时会发生什么呢?在这种情况下,是抛出异常,还是将返回类型更改为智能指针并返回nullptr
最后,返回一个对象集合。返回对象的容器(例如,
std::vector
)或(智能)指针的容器更好吗。在后一种情况下,哪些指针?情况1+2:我认为通过shared\u ptr
最初返回是有意义的,因为在这种设计中,DB连接似乎本质上是“可共享的”。这样,案例2就能自行解决
案例3:通过常量引用传递电影
。如果Movie
是一个类似值的类(并且没有任何昂贵的复制句柄之类的东西),那么带有const ref参数的store
的简单单一版本应该可以做到这一点,并保持代码简单
如果需要在fetch
方法中对“notfound”建模,请使用boost::optional
(或类似内容)作为返回值
最后一个案例:对于
电影
使用值集合(std::vector
)。(在C++11中,返回的向量将被移动。)编辑:我在这里说了一些不太聪明的事情,完全忽略了标题中的C++11
关于第3条和第5条的一些个人意见:
3) 我想不出任何理由在这里使用value来代替const引用。至少只要存储不是以某种非常不寻常的方式发生
最后一点:我总是希望有一个指针容器来最小化随机复制内存。在C++11中,您可能可以在它们中使用unique_ptr或shared_ptr,这取决于它们以后的用途
db=ConnectionFactory.get_连接(db_名称)#(1)创建数据库
联系
谁拥有db?什么时候被摧毁
std::unique\u ptr
std::unique_ptr
并将原始指针传递给其他对象时继续存在std::shared\u ptr
唯一的\u ptr
,除非它返回一个现有的共享连接,这种情况下它是一个共享的\u ptr
<代码>唯一\u ptr可以自动升级到共享\u ptr
模型=电影模型(db)#(2)
对象到关系映射器
std::move(db)
db.get()
const-Movie&
和Movie&
std::move(星球大战)
et=model.fetch(“E.T.”)(4)检索一个
反对
作为异常对象或可选
movies=model.fetch#all()#(5)检索所有
物体
std::vector
我建议您不要将智能指针视为指针,而是将其视为所有权:您用于一次只能有一个所有者的对象,而您可以用于可以有多个并发所有者的对象。因此,如果一个对象可能有多个所有者,我应该使用shared\u ptr
?是的,这是个好主意。@el.pescado或者,看看你是否可以安排你的代码,使对象有一个所有者和多个用户(所有者比所有其他用户都活得长)。然后您可以使用unique\u ptr
,它更简单,更容易推理。共享所有权不应该是唯一的选择default@jalf我认为,共享所有权比人为地创建比所有用户寿命更长的所有者要简单得多。只有在代码中自然发生这种情况时,我才会考虑这种方法。但是在一个许多不同的阶层并行地做许多不同的事情的环境中,仅仅分享所有权而不是试图猜测谁活得最长似乎更简单,也不容易出错。我同意这些答案。虽然我可能需要fetch\u all
获取一个输出迭代器,而不是返回任何内容。
star_wars = Movie("Star Wars", ...)
model.store(star_wars) # (3) Save object