从原始指针/引用创建智能指针
Create smart pointer from raw pointer / reference
我对C++很陌生,在指针/引用方面有问题。下面的例子反映了我的问题:
#include <iostream>
#include "boost/make_shared.hpp"
#include "boost/utility.hpp"
class UsedObjectInterface {
public:
virtual int data() const = 0;
};
class UsedObject : public UsedObjectInterface {
public:
UsedObject() : data_(42) {
}
explicit UsedObject(int value) : data_(value) {
}
int data() const {
return data_;
}
private:
const int data_;
};
class BaseClient : private boost::noncopyable {
public:
virtual const UsedObjectInterface& used_object() const = 0;
};
class SegmentationFaultClient : public BaseClient {
public:
// This can't work, since the object is deleted immediately.
// IMHO only the following two solutions can work:
// 1. The member attribute is not a reference (not possible with an abstract class, we lose the advantages of polymorphism).
// 2. The member attribute is a pointer.
SegmentationFaultClient() : used_object_(UsedObject()) {
}
explicit SegmentationFaultClient(const UsedObjectInterface& used_object)
: used_object_(used_object) {
}
const UsedObjectInterface& used_object() const {
return this->used_object_;
}
private:
const UsedObjectInterface& used_object_;
};
class CorrectClient : public BaseClient {
public:
CorrectClient() : used_object_(boost::make_shared<UsedObject>()) {
}
explicit CorrectClient(const boost::shared_ptr<UsedObjectInterface> used_object)
: used_object_(used_object) {
}
// TODO Is it possible to change this to a const&, so at least the interface
// is the same as in SegmentationFaultClient? Then the above constructor can
// be deleted.
explicit CorrectClient(const UsedObjectInterface& used_object)
: used_object_(&used_object) {
// TODO How-to convert a raw pointer to a smart pointer?
}
const UsedObjectInterface& used_object() const {
return *this->used_object_;
}
private:
const boost::shared_ptr<UsedObjectInterface> used_object_;
};
int main() {
SegmentationFaultClient segfault_client;
const UsedObjectInterface& a = segfault_client.used_object();
std::cout << a.data() << std::endl;
// Correct, but how to make this work with a const& constructor?
const UsedObject first_object;
CorrectClient correct_client(first_object);
const UsedObjectInterface& b = correct_client.used_object();
std::cout << b.data() << std::endl;
}
正如注释所说,SegmentationFaultClient
类的实现是完全错误的,因为默认构造函数在堆栈上创建了一个对象,该对象被"立即"删除。因此,我提出了使用指针的类CorrectClient
。我的目标是从SegmentationFaultClient
(const&
默认构造函数)中保留好的API(没有公共Boost)。上面的例子不能工作,并以以下错误终止:
invalid conversion from 'const UsedObjectInterface*' to 'boost::shared_ptr<UsedObjectInterface>::element_type* {aka UsedObjectInterface*}' [-fpermissive]
explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
所以我的问题是:有可能将原始指针*
转换为智能指针吗?如果是,最好的方法是什么?如果你看到我的代码有任何其他问题,也请告诉我!
问题是,您正试图将const-pointer
转换为non-const pointer
。您可以使用reference
作为参数,而不是const-reference
,或者您可以执行以下
const boost::shared_ptr<const UsedObjectInterface> used_object_;
然而,shared_ptr
的默认deleter将是delete
指针,在您的情况下,这不是在堆上分配的。您应该指向empty-deleter
,或者在这种情况下不使用shared_ptr
。
相关文章:
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何在没有数据拷贝的情况下从指针创建一个Eigen VectorXd对象
- 如何从绝对地址的 C 样式指针创建对C++对象的引用
- 不明白使用双指针 (**) 创建 2d 动态数组
- 如何使用指向动态数组的静态指针创建类?
- Opencl:从 c 样式指针创建 UserEvent
- 从 uint16 指针创建垫子
- 如何为指针创建类型定义
- 从原始指针创建const_iterator会在 macOS 上产生编译错误
- 为什么可以使用指针创建新结构,但不能以相同的方式创建双精度?
- 是否可以在 c++17 中为 c 样式指针或原始指针创建弱指针
- 调用虚拟函数而不通过类类型指针创建任何对象
- 如何使用双指针创建指针数组?
- 使用指针创建类成员
- 如何使用成员函数指针创建模板类
- 从现有指针C 创建一个新对象
- 使用指针创建动态数组的问题
- 如何为指向数组的指针创建内存集?
- 使用共享指针创建的链表数组
- 使用C++ 11 中的模板类型的成员函数指针创建方法参数