加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 继承自enable_shared_from_this返回self的shared_ptr的类的

发布时间:2020-12-16 07:14:42 所属栏目:百科 来源:网络整理
导读:我想知道是否还有像这样的伪代码: class A : public std::enable_shared_from_thisA { public: std::shared_ptrself_t getPtr(){ return std::static_pointer_castself_t(shared_from_this()); }};class B : public A { std::vectorA container; std::share
我想知道是否还有像这样的伪代码:

class A : public std::enable_shared_from_this<A> {
    public:
        std::shared_ptr<self_t> getPtr(){
            return std::static_pointer_cast<self_t>(shared_from_this());
        }
};

class B : public A {
    std::vector<A> container;

    std::shared_ptr<self_t> addChild(A child){
        container.push_back(child);
        return getPtr();
    }
};

class C : public B {
    public:
        std::shared_ptr<self_t> doSomething(){
            // something
            return getPtr();
        }
};

int main(){
    A obja = new A();
    C obj = new C();
    obj->addChild(obja)->doSomething()
}

我的目标是一个对象代表一个视图(如在MVC中的V中),以及能够为链式调用返回自身的方法.例如: – > setTop(0) – > addChild(child1) – > setBottom(0).

我已经读过,做一些重载<<<<<<<<<<<<运算符,但我没有看到工作得很好或看起来很漂亮. 我有一个想法是创建一个名为VIEW(名称,父级)的宏,它将使用模板扩展,但我遇到了自我引用的默认模板参数的问题. 任何帮助将不胜感激. – 编辑 – 在一个坚果shell中,我希望有一个继承自enable_shared_from_this的基类.基类将有一个方法,如doSomething返回共享指针.当派生类继承自基类时,我希望doSomething方法返回一个指向派生类的共享指针.我希望能够在不在派生类中覆盖doSomething的情况下执行此操作.

解决方法

这种概念将被存在于类定义之外的扩展方法所涵盖,不会违反类权限,但可以像方法一样调用…它存在于C#中但当前不存在于C中. C#中的代码如下所示:

// c# syntax
namespace MyBaseExtensions {
    public static class MyBaseExt {
        public static shared_ptr<T> getPtr<T>(this T self) where T : MyBase 
        {
            return static_pointer_cast<T>(self.shared_from_this());
        }
    }
}

这允许操作符链接,因为类行MyBase的每个继承都有自己的函数定义,因为该函数不是继承的方法,而是直接应用于每个相关类型.

反对的论点是,扩展通常使用不需要的功能来污染对象,并且独立模板函数将执行相同的操作.问题在于这个逻辑:

int main(){
    A obja = new A();
    C obj = new C();
    obj->getPtr()->addChild(obja)->doSomething()
}

最终看起来像

int main(){
    A obja = new A();
    C obj = new C();
    doSomething(addChild(getPtr(obj),obja)); //eyeroll.
}

你仍然会声明像这样的模板函数

// C++ syntax
namespace MyBaseExtensions {
    template<typename T> std::shared_ptr<T> getPtr<T>(T self)
    {
        return std::static_pointer_cast<T>(self->shared_from_this());
    }
}

至于将模板唯一地应用于每个派生类型的简单内部方式,我不确定.这样做的原因是你想要的功能不是方法继承,而是每个未来的类都会继承一个自动特化的模板(并且结果方法不会被继承或隐藏.)为此,C类需要有非继承的专用公共方法,当前访问权限不包括公共,私有和受保护或模板功能.

我很高兴找到一个很好的方法来拉开运算符链接.

因为我已经离开并浪费你的时间,我试图这样做:

#include <vector>
#include <memory>

// 0 argument,creates an overload method (and hides parent class method)
//           from template method func_name
// template method specialization of a parent method does not work
//      so we use C++11 automatic type deduction to figure the      
//         template return type and return what the template returns
#define FUNC_DEF_0(base,cur,func_name) 
    auto func_name() 
            -> decltype(base().func_name<cur>()) { 
        return base::func_name<cur>(); 
    }

// 1 argument
#define FUNC_DEF_1(base,func_name,arg1_t) 
    auto func_name(arg1_t param1) 
            -> decltype(base().func_name<cur>(param1)) { 
        return base::func_name<cur>(param1); 
    }

// class A
// add to class to hide class A methods
#define HIDE_A(current) 
    FUNC_DEF_0(A,current,getPtr)

class A : public std::enable_shared_from_this<A> {
public:
    template<typename _T = A>
    std::shared_ptr<_T> getPtr(){
        return std::static_pointer_cast<_T>(shared_from_this());
    }
};


// class B
// add to class to hide class B methods with new methods
#define HIDE_B(current) 
    HIDE_A(current) 
    FUNC_DEF_1(B,addChild,A)

class B : public A {
public:
    std::vector<A> container;

    template<typename _T = B>
    std::shared_ptr<_T> addChild(A child){
        container.push_back(child);
        return A::getPtr<_T>();
    }

    HIDE_A(B); // hide A methods with B specialized methods

    // Example method hiding
    // auto getPtr() -> decltype(A().getPtr<B>()) {
    //     return base::getPtr<B>();
    // }
};


// class C
// add to class to hide class C methods
#define HIDE_C(current) 
    HIDE_B(current) 
    FUNC_DEF_0(C,doSomething)

class C : public B {
public:
    template<typename _T = C>
    std::shared_ptr<_T> doSomething(){
        // something
        return A::getPtr<_T>();
    }
    HIDE_B(C); // hide B methods
};

int main() {
    auto obja = std::make_shared<A>();
    auto obj = std::make_shared<C>();
    obj->addChild(*obja)->doSomething();
}

编辑:修正了尝试.编译给我.

class A;

struct virtual_enable_shared_from_this_base :
    std::enable_shared_from_this<virtual_enable_shared_from_this_base> {
    virtual ~virtual_enable_shared_from_this_base() {}
};

#define HIDE_AMix(type) 
    using type::getPtr;

template<typename _T>
class AMix : public virtual virtual_enable_shared_from_this_base {
public:
    std::shared_ptr<_T> getPtr() {
        auto sptr = shared_from_this();
        return std::dynamic_pointer_cast<_T>(sptr);
    }
};

#define HIDE_BMix(type) 
    HIDE_AMix(type) 
    using type::addChild;

template<typename _T>
class BMix : public AMix<_T>{
public:
    std::vector<std::shared_ptr<A>> container;

    std::shared_ptr<_T> addChild(A* child){
        container.push_back(child->getPtr());
        return getPtr();
    }
};

#define HIDE_CMix(type) 
    HIDE_BMix(type) 
    using type::addChild;

template<typename _T>
class CMix : public BMix<_T>{
public:
    std::shared_ptr<_T> doSomething(){
        // something
        return getPtr();
    }
};


class A : public AMix<A> {
public:

};

class B : public A,public BMix<B> {
public:
    HIDE_AMix(BMix<B>);
    //using BMix<B>::getPtr;
    //using BMix<B>::addChild;
};

class C : public B,public CMix<C> {
public:
    HIDE_BMix(CMix<C>);
    //using CMix<C>::getPtr;
    //using CMix<C>::addChild;
    //using CMix<C>::doSomething;
};

int main() {
    auto obja = std::make_shared<B>();
    auto obj = std::make_shared<C>();
    obja->getPtr();
    obj->addChild(obja.get())->doSomething();
}

Edit2:这是摆弄模板的另一个版本.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读