【发布时间】:2013-11-26 11:28:07
【问题描述】:
我对 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;
}
正如 cmets 所说,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
所以我的问题是:是否可以将原始指针 * 转换为智能指针?如果是这样,最好的方法是什么?如果您发现我的代码有任何其他问题,也请告诉我!
【问题讨论】:
标签: c++ pointers boost reference smart-pointers