C++ 如何访问派生的std::shared\u ptr?
假设我有这样的代码,我想访问myClassB成员。我该怎么做?我需要使用functionA的功能。 我无法更改它,因为它来自第三方库。我需要使用functionA来创建它,并获得由它创建的值。在这种情况下,“Test_1”字符串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
类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";
}