gpt4 book ai didi

c++ - 从 enable_shared_from_this 返回 self 的 shared_ptr 继承的类的子类

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:16:12 26 4
gpt4 key购买 nike

我想知道是否有像这样的伪代码来做一些事情:

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()
}

我的目标是一个对象代表一个 View (如 MVC 中的 V),并且方法能够返回自身以进行链式调用。例如:->setTop(0)->addChild(child1)->setBottom(0) .

我读过,做一些像重载 << 这样的事情可能更容易理解。运算符,但我看不出它工作得很好或看起来很漂亮。

我的一个想法是制作一个名为 VIEW(name,parent) 的宏这将使用模板进行扩展,但我对自引用默认模板参数有疑问。

如有任何帮助,我们将不胜感激。

-- 编辑--

简而言之,我希望有一个基类继承自 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());
}
}
}

这允许运算符链接,因为类 Line 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());
}
}

至于将模板唯一地应用于每个派生类型的简单内部方法,我不确定。这样做的原因是你想要的功能不是方法继承,而是每个 future 的类继承一个它自动专门化的模板(并且由此产生的方法不是继承的就是隐藏的。)为此目的,C++ 类需要有非继承的专用公共(public)方法,当前访问权限 public、private 和 protected 或模板功能未涵盖。

如果找到一种实现运算符链接的好方法,我会非常高兴。

因为我已经离开并浪费了你的时间,所以我尝试了这个:

#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, cur, 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, current, 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, current, 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:这是摆弄模板的另一个版本。

关于c++ - 从 enable_shared_from_this 返回 self 的 shared_ptr 继承的类的子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34189711/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com