, , , ... #, ++. # :
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));
}
,
namespace MyBaseExtensions {
template<typename T> std::shared_ptr<T> getPtr<T>(T self)
{
return std::static_pointer_cast<T>(self->shared_from_this());
}
}
, . , , , , , ( ). ++ , , .
.
, :
#include <vector>
#include <memory>
#define FUNC_DEF_0(base, cur, func_name) \
auto func_name() \
-> decltype(base().func_name<cur>()) { \
return base::func_name<cur>(); \
}
#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); \
}
#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());
}
};
#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);
};
#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(){
return A::getPtr<_T>();
}
HIDE_B(C);
};
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(){
return getPtr();
}
};
class A : public AMix<A> {
public:
};
class B : public A, public BMix<B> {
public:
HIDE_AMix(BMix<B>);
};
class C : public B, public CMix<C> {
public:
HIDE_BMix(CMix<C>);
};
int main() {
auto obja = std::make_shared<B>();
auto obj = std::make_shared<C>();
obja->getPtr();
obj->addChild(obja.get())->doSomething();
}
Edit2: .