[英]Return pointer to derived class from base class
I would like to now if the following is possible.如果以下是可能的,我现在想。
I have a templated class called A
which inherits from a class called Base
.我有一个名为
A
的模板化 class ,它继承自名为Base
的 class 。 In Base
I set a write()
function to be rewritten for every derived class.在
Base
中,我设置了一个write()
function,为每个派生的 class 重写。
I am creating a vector to store the references of the Base
objects to be printer latter ( dataBase
).我正在创建一个向量来将
Base
对象的引用存储为打印机后者( dataBase
)。
I would like to know if it is possible to retrieve the reference of the A
object whose reference I passed to dataBase
.我想知道是否可以检索我传递给
dataBase
的A
object 的引用。
I have the following code:我有以下代码:
#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;
}
Best Regards此致
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
}
Note: when returning a reference, you need to return a reference to a valid object.注意:返回引用时,需要返回对有效 object 的引用。 You can't legally return a
nullptr
to signal failure, so instead we throw.你不能合法地返回一个
nullptr
来表示失败,所以我们抛出。
Usage:用法:
A<int>& getOne = lookup(dataBase, "one");
getOne.name2_ = "worked";
If you如果你
A<int>& getTwo = lookup(dataBase, "two");
getTwo.name2_ = "worked";
two will be found, but the type will not match and an A<int> &
can't be returned.将找到两个,但类型将不匹配并且
A<int> &
无法返回。 An exception will be thrown.将抛出异常。
If you如果你
A<int>& getFoo = lookup(dataBase, "foo");
getFoo.name2_ = "worked";
foo will not be be found and an A<int> &
can't be returned.将找不到 foo 并且无法返回
A<int> &
。 An exception will be thrown.将抛出异常。
Note: using a dynamic_cast
often means the base class interface is not sufficiently defined to make for a good base class.注意:使用
dynamic_cast
通常意味着基础 class 接口没有被充分定义以形成良好的基础 class。 See the Liskov Substitution Principle for a good test to see whether nor not inheritance is a good choice to use here.请参阅Liskov Substitution Principle进行很好的测试,看看 inheritance 是否是一个不错的选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.