3

我有几个类共享一个公共基类,只是它们的方法工作方式不同。所以在下面的例子中,加法器和乘法器是相同的,只是它们的计算方式不同。

有没有办法即时将“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

4 回答 4

7

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

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++ 开发人员,它可能不正确,或者其他人可能有更好的想法,只是尝试:)

于 2012-06-08T15:16:54.330 回答
5

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

在 C++ 中,按照您要求的方式进行操作是不可能的。

于 2012-06-08T15:15:09.217 回答
4

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

如果在上述重构之后有意义,您仍然可以在实用程序类中使用继承:在这种情况下,base 还将对 Data 对象进行操作,而不是 Data 本身

于 2012-06-08T15:15:39.253 回答
2

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

于 2012-06-08T15:21:25.420 回答