c ++多态和传递子类

时间:2015-05-12 15:10:42

标签: c++ inheritance

我正在考虑继承c ++,并尝试实现基本设置 基类有a)抽象方法fire(),子类必须实现,b)子类继承的变量someDouble

我目前的设置如下。这将无法编译,因为getDerivedObject()正在尝试返回抽象类。 (注意,如果可能的话,我宁愿保留BaseClass摘要。)

我尝试过的另一种方法是让AnotherClass返回指向对象的指针 - 但这不能用作object 将在超出范围时删除。

这是正确的整体方法吗?我可以从AnotherClass返回哪些内容,以便我可以getSomeDouble()BaseClassfire()访问DerivedClass

class BaseClass{
public:
    virtual void fire() = 0;
    // Use a getter and setter as you can't make a variable virtual in c++
    virtual double getSomeDouble(){ return someDouble; }
    virtual void setSomeDouble(double d){ someDouble = d; }

private:
    double someDouble;
};

class DerivedClass : public BaseClass{
public:
    void fire(){ cout << "Derived class fired. Yay." << endl; }
};


class AnotherClass{
public:
    // Set up a DerivedClass object and set someDouble to 1
    BaseClass getDerivedObject(){ // currrently fails; can't return an abstract class
        DerivedClass object;
        object.setSomeDouble(1);
        return object; // I will later want this to return vector<BaseClass> or similar
    };
};


int main()
{
    AnotherClass t;
    BaseClass o = t.getDerivedObject();
    BaseClass * p = &o;

    cout << to_string( (*p).getSomeDouble() );
    (*p).fire();
    return 0;
}

编辑:我尝试过使用这样的指针,当然,当对象离开范围时,该对象会被删除:

BaseClass * getDerivedObject(){
        DerivedClass object;
        object.setSomeDouble(1);
        BaseClass * p = &object;
        return p;
    };

1 个答案:

答案 0 :(得分:3)

使用unique_ptr s对多态对象进行伪常规访问。

template<class T>
using up=std::unique_ptr<T>;

// comes free in C++14
template<class T, class...Args>
up<T> make_unique( Args&&...args ) {
  return up<T>( new T(std::forward<Args>(args)...) );
}

up<BaseClass> getDerivedObject(){ // currrently fails; can't return an abstract class
    up<DerivedClass> object = make_unique<DerivedClass>();
    object->setSomeDouble(1);
    return object;
};

后:

up<BaseClass> o = t.getDerivedObject();

std::cout << to_string( o->getSomeDouble() );
o->fire();

这假设是C ++ 11。这是2015年,这似乎是安全的。

使用up<T>make_unique<T>以及std::vector< up<T> >意味着几乎不需要致电new。使用原始指针非常容易出错,这可以避免这种情况,同时仍然为您提供动态多态性。