将对象从一个派生类更改为另一个派生类

时间:2012-06-08 15:11:57

标签: c++ polymorphism

我有几个共享一个公共基类的类,但它们的方法工作方式不同。因此,在下面的示例中,除了执行计算的方式外,Adder和Multiplier是相同的。

有没有办法在运行中将“a”更改为乘数?我是否需要实现将派生类相互转换的方法?例如

之类的东西

a = a.asMultiplier()

正如您在下面的代码中看到的那样,我尝试将reinterpret_cast转换为乘数,没有运气,它仍然像加法器一样。 (gcc OS X v4.2.1)

#include <iostream>


class Base {
protected:
    int a,b;    
public:
    Base(int a, int b) {
        this->a = a;
        this->b = b;
    }  
    virtual ~Base() { }    
    virtual int calculate() = 0;
};


class Adder : public Base {    
public:
    Adder(int a, int b) : Base(a, b) {

    }      
    int calculate() {
        return this->a + this->b;
    }
};


class Multiplier : public Base {    
public:
    Multiplier(int a, int b) : Base(a, b) {    
    }  

    int calculate() {
        return this->a * this->b;
    }
};



int main() {

    Base* a = new Adder(3,4);
    Base* m = new Multiplier(3,4);

    std::cout << "Adder gives " << a->calculate() << std::endl;
    std::cout << "Multiplier gives " << m->calculate() << std::endl;

    a = reinterpret_cast<Multiplier*>(a);

    std::cout << "Now adder gives " << a->calculate() << std::endl;

    delete a;
    delete m;
    return 0;
}

4 个答案:

答案 0 :(得分:6)

我要解决这个问题的最好方法是实现一个复制构造函数,使用基类:

class Multiplier : public Base {    
public:
    Multiplier(int a, int b) : Base(a, b) {    
    }  

    explicit Multiplier(const Base& iBase) : Base(iBase.a, iBase.b) {    
    }  

    int calculate() {
        return this->a * this->b;
    }
};

但是因为我不是这里最先进的c ++开发人员,所以可能不正确,或者其他人可能有更好的想法,只是尝试:)

答案 1 :(得分:5)

我建议将对象的数据与其操作分离。这样,您可以轻松地从另一个对象构造一个对象,超越数据。因此,您的“转化”将如下所示:Multiplier m = new Multiplier(a);

在C ++中无法按照您的要求进行操作。

答案 2 :(得分:4)

在我看来,您需要对数据进行操作的实用程序类:将您的基类更改为Data类,其目的仅是存储数据并将数据显式传递给Adder,{{1等等。

如果在上面的重构之后有意义,你仍然可以在实用程序类中使用继承:在这种情况下,base也可以在Data对象上运行,而不是Data本身

答案 3 :(得分:2)

改变你的设计可能是个好主意。一般来说,我会说当基类和派生类共享某种共性时,使用继承是个好主意,不仅在数据方面,而且在行为方面。虽然没有直接建议,但我建议可能会阅读一些关于面向对象设计原则的书籍。尝试以你真正的方式来演绎类型是没有意义的。