继承和指针

时间:2017-12-07 18:57:00

标签: c++ oop inheritance std shared-ptr

我有这样的代码:

float a = M.ptr<float>(i)[j,k];

我知道这看起来很奇怪,但这是我能想到的最简单的情况,而不必写下我与rn挣扎的所有代码。有人可以解释,应该重载什么类型以及如何更改shared_ptr类型,知道它们来自同一个父类?

2 个答案:

答案 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*>类似,但后一种解决方案会泄漏内存。