我有这样的代码:
float a = M.ptr<float>(i)[j,k];
我知道这看起来很奇怪,但这是我能想到的最简单的情况,而不必写下我与rn挣扎的所有代码。有人可以解释,应该重载什么类型以及如何更改shared_ptr类型,知道它们来自同一个父类?
答案 0 :(得分:0)
对象无法更改类型。 Child
对象始终是Child
对象。你可以做的是用你想要的属性创建一个 new 对象并返回:
std::shared_ptr<Human> operator*(std::shared_ptr<Human> b, int x)
{
b->setAge(b->getAge()+x);
if(b->getAge()>18 && b->getSex()=="Man") {
return std::make_shared<Man>(b->getAge());
} else if(b->getAge()>18 && b->getSex()=="Woman") {
return std::make_shared<Woman>(b->getAge());
} else {
return b;
}
}
int main(){
std::shared_ptr<Human> x = std::make_shared<Child>;
x = x*19;
}
这似乎不是一个好的设计。 Human
作为儿童或成人的状态可以更好地表示为对象的属性,或者通过检查age
是否大于18的函数。
答案 1 :(得分:-2)
您无法使T<Derived>
类型继承自T<Base>
,因为C ++模板不支持协方差。这样做对于某些类型是不安全的,例如对容器的可变引用。 (想象一下,将std::vector<Cat>
称为std::vector<Animal>&
并推回一只狗!)
(我会将此答案作为评论,但我没有评论能力。)
更新: 您可以编写一个处理堆数据的非模板包装器:
class Wrapper
{
public:
Wrapper(Base* b) : raw(b) {}
~Wrapper() { delete raw; }
Base& get() { return *base; }
private:
Base* raw;
}
当然,在您的示例中,您使用std :: shared_ptr而不是std :: unique_ptr。您必须处理引用计数而不是简单地删除析构函数中的数据,但保持内部原始指针的技术仍然存在。
更新2:
上面的代码可以按原样用于提供间接级别,这样从基类继承的所有类都可以保存在同一类型中,而无需编写自己的引用计数器:
std::shared_ptr<Wrapper>
此解决方案可能与执行std::shared_ptr<Base*>
类似,但后一种解决方案会泄漏内存。