将子类作为父类传递给方法

4
class Method {
  public:    
  virtual void Rum();
};
class Euler : public Method {
  virtual void Rum() {
    printf("ahoj\n");
  }    
};
class Kutta : public Method {
  virtual void Rum() {
    printf("ahoj2\n");
  }    
};
class Simulator {
  public:
  Method *pointer;
  Simulator();
  void setmethod(Method m) { pointer = &m; }
};

int main() {
  Simulator s;
  s.setmethod(new Kutta());
  s.pointer->Rum();
  s.setmethod(new Euler());
  s.pointer->Rum();
}

我希望这个例子足够易懂。我尝试应用继承原则,但是出现了以下错误:(面向对象编程的知识在我的头脑中似乎有点混乱)

prog.cpp: In function ‘int main()’:
prog.cpp:26: error: no matching function for call to ‘Simulator::setmethod(Kutta*)’
prog.cpp:21: note: candidates are: void Simulator::setmethod(Method)
prog.cpp:28: error: no matching function for call to ‘Simulator::setmethod(Euler*)’
prog.cpp:21: note: candidates are: void Simulator::setmethod(Method)

那么,正确的方法是如何传递子代而不是其父代?谢谢!
2个回答

6

你的void setmethod(Method m)方法的签名不正确。为了匹配你的调用,它必须是void setmethod(Method* m)

另外,你需要在方法中使用引用或指针才能使多态工作 - 这意味着你不能通过值传递参数给setmethod并期望多态起作用。


谢谢您的回复。我尝试了一下,这是结果 - http://ideone.com/djw5tb - milanseitler
1
这是另一个问题 - 你声明了构造函数但没有定义它。请用Simulator() {}替换Simulator(); - SomeWittyUsername
好的,又出现了一个错误:http://ideone.com/1Yzq79 - milanseitler
即使定义了构造函数 http://ideone.com/2r8l48 - milanseitler
1
你没有在方法中定义 Rum。请定义它或将其变为纯虚拟函数:virtual void Rum() = 0; - SomeWittyUsername
终于成功了。非常感谢你的帮助。祝你有美好的一天! - milanseitler

4
这段代码是可以正常运行的:
#include <stdio.h>                                                                                                                                                                                                   

class Method {
  public:    
  virtual void Rum() = 0;
};
class Euler : public Method {
  virtual void Rum() {
    printf("ahoj\n");
  }    
};
class Kutta : public Method {
  virtual void Rum() {
    printf("ahoj2\n");
  }    
  virtual void Rum2() {
    printf("ahoj2blah\n");
  }    
};
class Simulator {
  public:
  Method *pointer;
//  Simulator(); // this was only declaration...
  void setmethod(Method* m) { pointer = m; }
};

int main() {
  Simulator s;
  s.setmethod(new Euler());
  s.pointer->Rum();
  s.setmethod(new Kutta());
  s.pointer->Rum();
//  s.pointer->Rum2(); //you can use only functions from Method
}

首先,您应该在方法中定义Rum函数。
同时,void setmethod(Method m)是不正确的,有两个原因:
  1. new总是返回指向对象的指针
  2. 最重要的原因是:
    编译器预期的是Method类型的对象,因此它为参数分配了sizeof(Method)字节的空间。
    不幸的是,继承对象往往具有附加变量,因此它们的大小大于其父对象的大小。这就是为什么函数不能接受继承类型的对象。
    好的解决方案是传递指向函数的指针,它始终具有8个字节。 不幸的是,您只能使用从中派生其他类的类中定义的方法和变量,但是当我们想要调用的函数是虚拟的时,将调用重载的函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接