我有几个共享一个公共基类的类,但它们的方法工作方式不同。因此,在下面的示例中,除了执行计算的方式外,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;
}
答案 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)
改变你的设计可能是个好主意。一般来说,我会说当基类和派生类共享某种共性时,使用继承是个好主意,不仅在数据方面,而且在行为方面。虽然没有直接建议,但我建议可能会阅读一些关于面向对象设计原则的书籍。尝试以你真正的方式来演绎类型是没有意义的。