C++ 如何访问派生的std::shared\u ptr?

C++ 如何访问派生的std::shared\u ptr?,c++,shared-ptr,smart-pointers,C++,Shared Ptr,Smart Pointers,假设我有这样的代码,我想访问myClassB成员。我该怎么做?我需要使用functionA的功能。 我无法更改它,因为它来自第三方库。我需要使用functionA来创建它,并获得由它创建的值。在这种情况下,“Test_1”字符串 类myClassA{ 公众: myClassA(){} ~myClassA(){} }; 类别myClassB:公共myClassA { 公众: myClassB(){} void setString1(std::string newString) std::strin

假设我有这样的代码,我想访问myClassB成员。我该怎么做?我需要使用functionA的功能。 我无法更改它,因为它来自第三方库。我需要使用functionA来创建它,并获得由它创建的值。在这种情况下,“Test_1”字符串

类myClassA{
公众:
myClassA(){}
~myClassA(){}
};
类别myClassB:公共myClassA
{
公众:
myClassB(){}
void setString1(std::string newString)
std::string getS1()
私人:
std::字符串私有成员;
};
std::shared_ptr function()
{
std::shared_ptr temporary(新的myClassB());
临时->设置字符串1(“测试_1”);
返回标准::移动(临时);
}
int main()
{
std::shared_ptr myPtr;/=functionA()??
}

理论上,您可以使用
动态\u转换
(或者在本例中,特别是
std::dynamic\u pointer\u转换
)来获取派生指针类型。如下所示:

std::shared_ptr<MyClassA> a_ptr = functionA();
std::shared_ptr<MyClassB> b_ptr = std::dynamic_pointer_cast<MyClassB>(a_ptr);
if(b_ptr) {//Check to verify the cast was successful
    b_ptr->setString("Test1");
}

从理论上讲,您可以使用
dynamic\u cast
(或者在本例中特别是
std::dynamic\u pointer\u cast
)来获取派生指针类型。如下所示:

std::shared_ptr<MyClassA> a_ptr = functionA();
std::shared_ptr<MyClassB> b_ptr = std::dynamic_pointer_cast<MyClassB>(a_ptr);
if(b_ptr) {//Check to verify the cast was successful
    b_ptr->setString("Test1");
}

同意
dynamic\u cast
但如果ClassA中没有虚拟函数表,则必须执行以下操作:

#包括
#包括
#包括
#包括
类别myClassA{
公众:
myClassA(){}
~myClassA(){}
};
类别myClassB;
类B_注册表{
私人:
ClassB_注册表(){
}
~ClassB_注册表(){
}
公众:
静态ClassB_注册表*Get(){static ClassB_注册表obj;return&obj;}
静态无效寄存器(myClassB*ptr){
Get()->mPointers.insert(ptr);
}
静态无效注销(myClassB*ptr){
Get()->mPointers.erase(ptr);
}
静态myClassB*Cast(myClassA*ptr){
如果(Get()->mPointers.count((myClassB*)ptr)>0)返回(myClassB*)ptr;
返回空ptr;
}
私人:
std::设置mPointers;
};
类别myClassB:公共myClassA
{
公众:
myClassB(){ClassB_注册表::寄存器(this);}
~myClassB(){ClassB_Registry::UnRegister(this);}
void setString1(std::string newString){privatember=newString;}
std::string getS1(){return privatember;}
私人:
std::字符串私有成员;
};
std::shared_ptr function()
{
std::shared_ptr temporary(新的myClassB());
临时->设置字符串1(“测试_1”);
返回标准::移动(临时);
}
int main()
{
std::shared_ptr myPtr=functionA();/??
std::shared_ptr myPtr_a(new myClassA());/??
myClassB*pDerrived=ClassB_Registry::Cast(myPtr.get());//填补RTTI的空白
如果(pDerrived)
std::coutgets1();
pDerrived=ClassB_Registry::Cast(myPtr_a.get());//在指针上工作以返回null
如果(pDerrived)

std::cout getS1()同意
dynamic_cast
,但如果ClassA中没有虚拟函数表,则必须执行以下操作:

#包括
#包括
#包括
#包括
类别myClassA{
公众:
myClassA(){}
~myClassA(){}
};
类别myClassB;
类B_注册表{
私人:
ClassB_注册表(){
}
~ClassB_注册表(){
}
公众:
静态ClassB_注册表*Get(){static ClassB_注册表obj;return&obj;}
静态无效寄存器(myClassB*ptr){
Get()->mPointers.insert(ptr);
}
静态无效注销(myClassB*ptr){
Get()->mPointers.erase(ptr);
}
静态myClassB*Cast(myClassA*ptr){
如果(Get()->mPointers.count((myClassB*)ptr)>0)返回(myClassB*)ptr;
返回空ptr;
}
私人:
std::设置mPointers;
};
类别myClassB:公共myClassA
{
公众:
myClassB(){ClassB_注册表::寄存器(this);}
~myClassB(){ClassB_Registry::UnRegister(this);}
void setString1(std::string newString){privatember=newString;}
std::string getS1(){return privatember;}
私人:
std::字符串私有成员;
};
std::shared_ptr function()
{
std::shared_ptr temporary(新的myClassB());
临时->设置字符串1(“测试_1”);
返回标准::移动(临时);
}
int main()
{
std::shared_ptr myPtr=functionA();/??
std::shared_ptr myPtr_a(new myClassA());/??
myClassB*pDerrived=ClassB_Registry::Cast(myPtr.get());//填补RTTI的空白
如果(pDerrived)
std::coutgets1();
pDerrived=ClassB_Registry::Cast(myPtr_a.get());//在指针上工作以返回null
如果(pDerrived)

std::cout getS1()谢谢你的回答,但我需要使用function来创建pointer@pZCZ那很好。
std::make_shared
只是
function
在其第一行代码中所做的语法糖。不过,我不知道如何获得function设置的值。在这种情况下,我需要获得“TEST_1”字符串。很抱歉没有具体说明。@pZCZ在
if
语句中,在验证
b_ptr
的有效性之后,
b_ptr
是一个100%真实的指针,指向类型为
MyClassB
的对象。它可以与任何其他指向
MyClassB
的指针一样使用。因此,您可以调用
b_ptr->getS1()
,它将完全完成您期望它做的事情。就范围而言,编写
if(auto const b_ptr=std::dynamic_pointer_cast(a_ptr)){/*使用b_ptr*/}将更加简洁和整洁
谢谢您的回答,但我需要使用Function创建pointer@pZCZ那很好。
std::make_shared
只是
function
在其第一行代码中所做的语法糖。不过,我不知道如何获得function设置的值。在这种情况下,我需要获得“TEST_1”字符串。很抱歉没有具体说明。@pZCZ在
if
语句中,在验证
b_ptr
的有效性之后,
b_ptr
是一个100%真实的指针,指向类型为
MyClassB
的对象。它可以与任何其他指向
MyClassB
的指针一样使用。因此,您可以调用
b_ptr->getS1()
,它将完全完成您期望它做的事情。就范围而言,编写
如果(auto const b_ptr=std::dynamic_pointer_cast(a_ptr)){/*
class MyClassA {
public:
    MyClassA() = default;
    virtual ~MyClassA() = default;
};
#include <string>
#include <memory>
#include <iostream>
#include <set>

class myClassA {
public:
    myClassA(){}
    ~myClassA(){}
};

class myClassB;
class ClassB_Registry{
    private:
    ClassB_Registry(){
    }
    ~ClassB_Registry(){
    }
    public:
    static ClassB_Registry* Get(){ static ClassB_Registry obj; return &obj; }
    static void Register(myClassB* ptr){
        Get()->mPointers.insert(ptr);
    }
    static void UnRegister(myClassB* ptr){
        Get()->mPointers.erase(ptr);
    }
    static myClassB* Cast(myClassA* ptr){
        if(Get()->mPointers.count((myClassB*)ptr) > 0) return (myClassB*)ptr;
        return nullptr;
    }

    private:
    std::set<myClassB*> mPointers;
};



class myClassB : public myClassA
{
public:
myClassB(){ ClassB_Registry::Register(this); }
~myClassB(){ ClassB_Registry::UnRegister(this); }
void setString1(std::string newString){privateMember = newString;}
std::string getS1() { return privateMember; }
private:
std::string privateMember;
};

std::shared_ptr<myClassA> functionA()
{
std::shared_ptr<myClassB> temporary(new myClassB());
temporary->setString1("TEST_1");
return std::move(temporary);
}

int main()
{
std::shared_ptr<myClassA> myPtr = functionA(); //??
std::shared_ptr<myClassA> myPtr_a(new myClassA()); //??
myClassB* pDerrived = ClassB_Registry::Cast(myPtr.get()); // bridge the RTTI gap
if(pDerrived) 
    std::cout << pDerrived->getS1();

pDerrived = ClassB_Registry::Cast(myPtr_a.get()); // works on A pointers to return null
if(pDerrived) 
    std::cout << pDerrived->getS1() << "    \n";
else
    std::cout << "Not A Pointer of Type B" << "    \n";
}