当我可以简单地使用std::unique/shared_ptr(std::vector<>)
时,我对std::vector<>
的主要用法有些困惑,据我所知,@Configuration
@EnableTransactionManagement
@EnableSwagger2
@EnableJpaRepositories(basePackages = "com.restfulproject.crud.repositories")
@ComponentScan(basePackages = "com.restfulproject.crud.*")
public class WebConfig extends WebMvcConfigurationSupport{
@Bean
public Docket userApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
.apiInfo(metaData());
}
@Primary
@Bean
public SwaggerResourcesProvider swaggerResourcesProvider(InMemorySwaggerResourcesProvider defaultResourcesProvider) {
return () -> {
SwaggerResource wsResource = new SwaggerResource();
wsResource.setName("swagger");
wsResource.setSwaggerVersion("2.0");
wsResource.setLocation("/api/config/swagger.json");
List<SwaggerResource> resources = new ArrayList<>(defaultResourcesProvider.get());
resources.add(wsResource);
return resources;
};
}
@Bean
WebMvcConfigurer configurer () {
return new WebMvcConfigurerAdapter() {
@Override
public void addResourceHandlers (ResourceHandlerRegistry registry) {
registry.addResourceHandler("/api/config/swagger.json").
addResourceLocations("classpath:/config/swagger.json");
}
};
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController("/api/v2/api-docs", "/v2/api-docs");
registry.addRedirectViewController("/api/swagger-resources/configuration/ui", "/swagger-resources/configuration/ui");
registry.addRedirectViewController("/api/swagger-resources/configuration/security", "/swagger-resources/configuration/security");
registry.addRedirectViewController("/api/swagger-resources", "/swagger-resources");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/api/swagger-ui.html**").addResourceLocations("classpath:/META-INF/resources/swagger-ui.html");
registry.addResourceHandler("/api/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
private ApiInfo metaData() {
return new ApiInfoBuilder()
.title("User Crud REST API")
.description("\"Projeto que utiliza spring boot\"")
.version("1.0.0")
.license("Apache License Version 2.0")
.licenseUrl("https://www.apache.org/licenses/LICENSE-2.0\"")
.build();
}
}
本身就是一个动态数组。正如我在周围所看到的,人们说这两者之间没有任何性能差异。因此,基于所有这些,使用指向容器(在本例中为向量)而不是向量的智能指针有什么意义?
答案 0 :(得分:2)
首先,除非您需要与std::shared_ptr
相关的特定“共享所有权”语义,否则不应该使用std::shared_ptr
。如果需要智能指针,则默认情况下应默认为std::unique_ptr
,并且仅在明确需要时才离开它。
第二:表面上,相比std::unique_ptr<TYPE>
,更喜欢TYPE
的原因是如果您计划将对象移动很多。这是不可移动或移动昂贵的大型对象的通用设计范例。他们实现了一个Copy构造函数,而没有实现Move构造函数,因此移动被迫表现得像Copy。
std::vector
确实具有相对有效的移动语义:如果移动std::vector
,无论其包含的类型有多复杂,该移动仅构成几个指针交换。移动std::vector
并不会招致大量的计算复杂性,这没有真正的风险。即使在您覆盖先前分配的数组(调用向量中所有对象的析构函数)的情况下,如果您使用std::unique_ptr<std::vector<TYPE>>
来代替,那么您仍然会遇到这种复杂性,什么都不做。
std::unique_ptr<std::vector<TYPE>>
有两个优点。第一个是它摆脱了隐式副本构造函数。也许您想强制维护程序员不要复制该对象。但这是相当利基的用途。另一个优点是,它允许您规定没有向量的情况,即vec.size() == 0
与doesNotExist(vec)
的条件不同。但是即使在那种情况下,您也应该更喜欢std::optional<std::vector>
,它可以更好地通过代码传达对象的意图。当然,std::optional
仅在C ++ 17→代码中可用,因此也许您处于尚未实现它的环境中。但是否则,没有理由使用std::unique_ptr<std::vector>
。
因此,总的来说,我不认为std::unique_ptr<std::vector>
有实际用途。它和std::vector
之间没有实际的性能差异,使用它只会使您的代码变得不必要地复杂。