저는 C++을 처음 사용하고 포인터/참조와 관련하여 문제가 있습니다. 코멘트가 기본 생성자는 "즉시"제거 스택에 객체를 생성하기 때문에, SegmentationFaultClient
클래스의 implementaton은 단순히 잘못 말하는 것처럼원시 포인터/참조에서 스마트 포인터 만들기
#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;
}
: 다음 예는 내 문제를 반영한다. 따라서 포인터를 사용하는 클래스 CorrectClient
을 생각해 냈습니다. 내 목표는 SegmentationFaultClient
(const&
기본 생성자)에서 좋은 API (공개 부스트 없음)를 유지하는 것입니다. 위의 예는 하지 작업을 수행하고 다음과 같은 오류와 함께 종료 :
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' 스마트 포인터만을 만들었습니다. 힌트를 주셔서 감사합니다! 나는 당신의 마지막 문장을 완전히 이해하지 못한다. 추가 정보를 제공해 줄 수 있습니까? –
@FlorianWolters http://www.boost.org/doc/libs/1_54_0/libs/smart_ptr/shared_ptr.htm deleter가있는 생성자를 사용합니다. 함수는 아무 것도 수행하지 않습니다. – ForEveR
Btw, 그런 상황을 다루기위한 귀하의 추천은 무엇입니까? 두 접근법 모두 "원시 포인터"동작을 생성합니다. 나는 기본 생성자와 완전한 생성자를 원한다. 기본 생성자는 다른 클래스의 인스턴스를 만들어야하지만 전체 생성자는 동일한 클래스의 인수를 하나 가져야합니다. "최고의 연습"C++ 메모리 소유권 접근법이 있습니까? –