c – 继承自enable_shared_from_this返回self的shared_ptr的类的
我想知道是否还有像这样的伪代码:
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:这是摆弄模板的另一个版本. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- react 楼层按需加载 @loadable/component
- 解决UbuntuServer1.14.10安装build-essential等软件依赖lib
- 详解C++ 拷贝构造函数和赋值运算符
- 返回错误410的位置正则表达式?在nginx
- 使用C/C++以外的语言构建共享库特别是prolog
- postgresql – 在postgres中的WHERE子句中的Concat
- PostgreSQL GUC 参数级别介绍
- 关于flashback table tablename to before drop的应用—恢复
- Enterprise Test Driven Develop
- oracle to_char格式数值