Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 安全启用此用法中的\u共享\u 请考虑以下简化示例: #include "boost/shared_ptr.hpp" #include "boost/smart_ptr/enable_shared_from_this.hpp" using namespace boost; class State : public boost::enable_shared_from_this<State> { public: shared_ptr<State> GetSelf() { return shared_from_this(); }; // returns following state virtual shared_ptr<State> Execute() = 0; }; template<typename T> shared_ptr<T> Create() { return shared_ptr<T>(new T); } class MyState2; class MyState1 : public State { virtual shared_ptr<State> Execute() { if (change of state) return Create<MyState2>(); else return GetSelf(); }; }; class MyState2 : public State { virtual shared_ptr<State> Execute() { if (change of state) return Create<MyState1>(); else return GetSelf(); }; }; int main(int argc, char* argv[]) { shared_ptr<State> pCurrentState = Create<MyState1>(); // <-- OK // State* pCurrentState(new MyState1); // <-- Runtime error while (...) pCurrentState = pCurrentState->Execute(); return 0; } #包括“boost/shared#ptr.hpp” #包括“boost/smart\u ptr/enable\u shared\u from\u this.hpp” 使用名称空间boost; 类状态:public boost::从\u启用\u共享\u { 公众: 共享\u ptr GetSelf() { 从_this()返回共享的_; }; //返回以下状态 虚拟共享_ptr Execute()=0; }; 模板 共享\u ptr Create() { 返回共享ptr(新T); } 第2类; 类MyState1:公共状态 { 虚拟共享\u ptr Execute() { if(状态变更) 返回Create(); 其他的 返回GetSelf(); }; }; 类MyState2:公共状态 { 虚拟共享\u ptr Execute() { if(状态变更) 返回Create(); 其他的 返回GetSelf(); }; }; int main(int argc,char*argv[]) { shared_ptr pCurrentState=Create();//_C++_Boost - Fatal编程技术网

C++ 安全启用此用法中的\u共享\u 请考虑以下简化示例: #include "boost/shared_ptr.hpp" #include "boost/smart_ptr/enable_shared_from_this.hpp" using namespace boost; class State : public boost::enable_shared_from_this<State> { public: shared_ptr<State> GetSelf() { return shared_from_this(); }; // returns following state virtual shared_ptr<State> Execute() = 0; }; template<typename T> shared_ptr<T> Create() { return shared_ptr<T>(new T); } class MyState2; class MyState1 : public State { virtual shared_ptr<State> Execute() { if (change of state) return Create<MyState2>(); else return GetSelf(); }; }; class MyState2 : public State { virtual shared_ptr<State> Execute() { if (change of state) return Create<MyState1>(); else return GetSelf(); }; }; int main(int argc, char* argv[]) { shared_ptr<State> pCurrentState = Create<MyState1>(); // <-- OK // State* pCurrentState(new MyState1); // <-- Runtime error while (...) pCurrentState = pCurrentState->Execute(); return 0; } #包括“boost/shared#ptr.hpp” #包括“boost/smart\u ptr/enable\u shared\u from\u this.hpp” 使用名称空间boost; 类状态:public boost::从\u启用\u共享\u { 公众: 共享\u ptr GetSelf() { 从_this()返回共享的_; }; //返回以下状态 虚拟共享_ptr Execute()=0; }; 模板 共享\u ptr Create() { 返回共享ptr(新T); } 第2类; 类MyState1:公共状态 { 虚拟共享\u ptr Execute() { if(状态变更) 返回Create(); 其他的 返回GetSelf(); }; }; 类MyState2:公共状态 { 虚拟共享\u ptr Execute() { if(状态变更) 返回Create(); 其他的 返回GetSelf(); }; }; int main(int argc,char*argv[]) { shared_ptr pCurrentState=Create();//

C++ 安全启用此用法中的\u共享\u 请考虑以下简化示例: #include "boost/shared_ptr.hpp" #include "boost/smart_ptr/enable_shared_from_this.hpp" using namespace boost; class State : public boost::enable_shared_from_this<State> { public: shared_ptr<State> GetSelf() { return shared_from_this(); }; // returns following state virtual shared_ptr<State> Execute() = 0; }; template<typename T> shared_ptr<T> Create() { return shared_ptr<T>(new T); } class MyState2; class MyState1 : public State { virtual shared_ptr<State> Execute() { if (change of state) return Create<MyState2>(); else return GetSelf(); }; }; class MyState2 : public State { virtual shared_ptr<State> Execute() { if (change of state) return Create<MyState1>(); else return GetSelf(); }; }; int main(int argc, char* argv[]) { shared_ptr<State> pCurrentState = Create<MyState1>(); // <-- OK // State* pCurrentState(new MyState1); // <-- Runtime error while (...) pCurrentState = pCurrentState->Execute(); return 0; } #包括“boost/shared#ptr.hpp” #包括“boost/smart\u ptr/enable\u shared\u from\u this.hpp” 使用名称空间boost; 类状态:public boost::从\u启用\u共享\u { 公众: 共享\u ptr GetSelf() { 从_this()返回共享的_; }; //返回以下状态 虚拟共享_ptr Execute()=0; }; 模板 共享\u ptr Create() { 返回共享ptr(新T); } 第2类; 类MyState1:公共状态 { 虚拟共享\u ptr Execute() { if(状态变更) 返回Create(); 其他的 返回GetSelf(); }; }; 类MyState2:公共状态 { 虚拟共享\u ptr Execute() { if(状态变更) 返回Create(); 其他的 返回GetSelf(); }; }; int main(int argc,char*argv[]) { shared_ptr pCurrentState=Create();//,c++,boost,C++,Boost,在一般情况下,没有办法做您想要做的事情 如果Base不是基类(即:它们不应该派生自基类),那么这很容易。将构造函数设为工厂函数,并将构造函数设为私有。因此,它们必须经过您的工厂,因此您可以确保它们使用shared_ptr来包装它们 但是,如果您允许用户从中派生类,那么所有赌注都是无效的。因此,您需要考虑两件事: 我真的需要从这里启用共享吗 我真的需要允许继承吗 1:您发布的代码根本没有给出您需要使用启用\u shared\u from\u this的原因。您使用它的唯一位置是在一个函数中,该函数

在一般情况下,没有办法做您想要做的事情

如果
Base
不是基类(即:它们不应该派生自基类),那么这很容易。将构造函数设为工厂函数,并将构造函数设为私有。因此,它们必须经过您的工厂,因此您可以确保它们使用
shared_ptr
来包装它们

但是,如果您允许用户从中派生类,那么所有赌注都是无效的。因此,您需要考虑两件事:

  • 我真的需要从这里启用共享吗
  • 我真的需要允许继承吗
  • 1:您发布的代码根本没有给出您需要使用
    启用\u shared\u from\u this
    的原因。您使用它的唯一位置是在一个函数中,该函数向该实例返回
    shared\u ptr
    。那么,它将它返回给谁?该对象的用户。谁只能通过拥有
    shared\u ptr

    简而言之:你给他们一些他们必须已经有权访问的东西。这个功能是无用的

    嗯,除非你违反了
    shared\u ptr
    的正确使用,否则它是没有用的。一般来说,一旦你将指针包装在
    shared\u ptr
    中,你要么保持这种方式,要么用它制作一个
    弱的\u ptr
    。你几乎从不给某人一个指向该对象的裸指针。如果你这样做了,那么这应该是一个明确的信号,表明他们是存储该指针,或期望以任何方式、形状或形式维护其任何形式的所有权

    因此,他们能够从裸指针获得
    共享\u ptr
    ,这是一个糟糕的设计

    enable_shared_from_此
    用于指向无法避免的
    shared_ptr
    保留对象的裸指针:
    。它的存在是因为成员函数可能需要使用指向该对象的指针调用外部函数,但该外部函数采用
    shared_ptr
    weak_ptr
    而不是裸指针。这不是允许糟糕设计的一种方式

    2:您正在构建一个状态机。那么为什么基类的
    状态
    需要派生自
    启用\u共享\u自\u此
    ?如果派生类的
    执行
    方法将返回自身,则由该派生类来处理它。提供该方法不应由基类负责。而且当然不应该由公共功能提供


    简而言之,如果每个派生类想要返回指向自身的指针,那么它需要从
    中继承并启用\u shared\u from\u this
    。因此,用户的责任是保持这些内容的正确性,而不是您的正确性。

    防止非托管实例的最简单方法是将每个派生类的构造函数设置为私有Function需要是其创建的类的朋友或成员;如果要保留factory模板,则需要在派生类之前声明它,以便使其成为朋友:

    template<typename T>
    shared_ptr<T> Create()
    {
        return shared_ptr<T>(new T);
    }
    
    class Derrived : public Base
    {
    private:
        friend shared_ptr<Derrived> Create<Derrived>();
        Derrived() {}
        // Client implementation goes here
    };
    

    你确定你真的想在这种定制中使用继承吗?也许某种包含关系会更好;一般来说,对于那些与
    shared\u ptr
    紧密相关的东西,这种关系会更好,它们需要
    从这个
    中启用\u shared\u。真的很奇怪。
    boost的默认构造函数::enable_shared_from_此
    只会创建一个空的
    弱\u ptr
    对象。如果所有实例都由共享指针管理,为什么您需要
    GetSelf()
    呢?它唯一的用途是从非托管指针/引用获取共享指针,您说这是不允许的。您只需要
    shared_from_this()
    如果你出于某种原因需要从成员函数中获取共享指针,那就可以了。我不确定,但是包含关系如何帮助你呢?你能更具体一点吗?对不起,注释是指Nicol Bolasi如果
    Base
    的构造函数是私有的,我相当肯定你不能从中派生,因为你必须调用e构造函数。@Nicol:正确,
    Base
    的构造函数不能是私有的。正如我说的,“使每个派生类的构造函数都是私有的”。我认为强制执行它的目的是,如果一个类依赖于此
    中的
    共享_,那么如果不将其放入
    共享_ptr
    ,您将无法创建该类。一个好的API很容易正确使用,也很难错误使用。我也想到了这一点:使基类构造函数受到保护,但您无法确保DRIVED类的构造函数也受到保护,因此仍然有可能创建它的不受控制的实例。请考虑已编辑的例子,我希望我的意图现在更清楚。@ Rays:我添加了一个如何处理它的解释。这个想法是由一个简单地周期性调用PNEW的实例驱动状态机。并将结果状态设置为ist当前状态,不使用m
    class State : public boost::enable_shared_from_this<State>
    {
    public:
        // returns following state
        friend shared_ptr<State> Execute(shared_ptr<State> state) {
            return state->Execute();
        }
    private:
        virtual shared_ptr<State> Execute() = 0;
    };
    
    class MyState : public State
    {
        shared_ptr<State> Execute() {return shared_from_this();}
    };
    
    int main(int argc, char* argv[])
    {
        shared_ptr<State> state1(new MyState);  // <-- OK
        State * state2(new MyState);            // <-- OK, but can't be used
        Execute(state1);                        // <-- OK
        // Execute(state2);                     // <-- Error
        // state2->Execute();                   // <-- Error
    }