从基类返回指向派生类的指针

Return pointer to derived class from base class

本文关键字:指针 派生 基类 返回      更新时间:2024-05-10

如果可以的话,我现在想。

我有一个名为A的模板化类,它继承了一个称为Base的类。在Base中,我为每个派生类设置了一个要重写的write()函数。

我正在创建一个向量来存储Base对象的引用,这些对象将成为打印机后一个对象(dataBase(。

我想知道是否可以检索我传递给dataBaseA对象的引用。

我有以下代码:

#include <iostream>
#include <string>
#include <array>
#include <vector>
class Base
{
public:
Base(std::string name):name_(name){}
virtual ~Base(){}
virtual void write()=0;
const std::string& name() const
{
return name_;
}

private:
std::string name_;
};
template< typename T>
class A : public Base
{
public:
A(std::string name):Base(name),name2_(name + "test"){}
~A(){}
void write();
std::string name2_;
};
template< typename T>
void A<T>::write()
{
std::cout <<  name2_ << std::endl;
}

int main()
{

A<int> one("one");
A<double> two("two");
A<std::array<double,4>> three("three");
std::vector<Base*> dataBase;
dataBase.push_back(&one);
dataBase.push_back(&two);
dataBase.push_back(&three);
for(auto i : dataBase)
{
i->write();
}
A<int>& getOne = lookup("one"); // this is what I want to create
getOne.name2_  = "worked";
for(auto i : dataBase)
{
i->write();
}
return 0;
}

致以最诚挚的问候

A<int>& lookup(std::vector<Base*> & dataBase, // need to provide database
const std::string & seeking)
{
// find a match
auto found = std::find_if(dataBase.begin(),
dataBase.end(),
[seeking](Base * item)
{
return item->name() == seeking;
});
if (found != dataBase.end())
{ // found it
// convert to A<int>
A<int> * temp = dynamic_cast<A<int>*>(*found);
if (temp) // dynamic_cast returns nullptr on failure.
{ // successful conversion
return *temp; // return it.
}
throw std::runtime_error("wrong type"); // What we found isn't the desired type
}
throw std::runtime_error("not found"); // Couldn't find a match
}

注意:返回引用时,需要返回对有效对象的引用。你不能合法地返回一个nullptr来表示失败,所以我们抛出。

用法:

A<int>& getOne = lookup(dataBase, "one");
getOne.name2_  = "worked";

如果你

A<int>& getTwo = lookup(dataBase, "two");
getTwo.name2_  = "worked";

将找到两个,但类型不匹配,并且无法返回A<int> &。将引发异常。

如果你

A<int>& getFoo = lookup(dataBase, "foo");
getFoo.name2_  = "worked";

将找不到foo,并且无法返回A<int> &。将引发异常。

注意:使用dynamic_cast通常意味着基类接口的定义不足以形成一个好的基类。请参阅Liskov替换原则以获得一个好的测试,看看继承是否是在这里使用的好选择。

std::find_if文件

dynamic_cast文件