C++中的多态性
Polymorphism in C++
这是我的代码:
#include <cstdlib>
#include <iostream>
#include <cstring>
using namespace std;
class person {
string name;
public:
person(const string &n){
name=n;
}
virtual person& print(const person&){}
};
class worker:public person {
int number;
public:
worker(const string &n , int num ):person(n){
number=num;
}
virtual worker& print(const worker& x){
cout << number << x.number<< endl;
return number+=number;
}
};
int main(int argc, char** argv) {
person *p = new worker("john",1);
person *g = new worker("jack",2);
int c = p->print(*g);
return 0;
}
所有的工人都是人,但不是所有的人都是工人。工人是人的子阶层。我的问题在于打印方法。我不知道如何正确地设计类之间的关系。
在这个代码中,结果将为空,因为主函数调用了person类的print方法。我需要的是使用多态性来调用worker的方法print。
我可以用这个:
virtual worker& print(const person& x){
cout << number << x.number<< endl;
}
上面的代码调用了正确的方法,但person类中没有数字属性。所以这也不起作用。
有人能帮助我如何正确设计我的程序吗?我需要调用祖先类上的print函数,这样它就可以将调用重定向到正确的类。这是一个非常简单的例子,有更多的子类,所以它需要保持关系person>worker。
感谢任何人的帮助。
正如您已经注意到的,父类中的方法无法看到仅在其子类中定义的成员。如果你想一想,这很有意义,因为父类在编译时不可能知道它可能的子类是什么,那么它怎么可能知道它们的新数据成员呢?
正确的方法是使Person
类中的print()
方法纯虚拟,并为每个子类编写一个单独的print()
方法,因为只有子类才能访问其私有数据成员。
virtual void print() = 0;
请注意,该函数不再接受参数,并且它在子类中的实现应该打印自己的number
以及他们想要打印的任何其他成员。
这段代码很奇怪。要打印,您不需要传入person
或worker
。
class person
{
public: virtual void print(){ cout << name; }
};
class worker : public person
{
public: virtual void print(){ person::print(); cout << ": " << number; }
};
int main()
{
person *p = new worker( "john", 1 ),
*q = new worker( "jack", 2 );
p->print();
q->print();
return 0;
}
您的两个print
函数在返回和参数类型上都有所不同。所以他们除了名字没有任何共同点。此外,在运行时,计算机不知道Person
、p
和q
指向哪种"类型"。因此,您需要给print
一个统一的签名,例如:
class Person
{
public:
virtual int print(Person* other) {}
}
我假设您希望print
返回int
,因为您编写了int c = p->print(*g);
。我还使用了一个指针来使用变量类型作为参数。在Worker
和其他派生类中,您可以编写以下内容:
int print(Person* other)
{
Worker* worker = dynamic_cast<Worker*>(other);
if (worker)
{
std::cout << number << " " << worker->number << std::endl;
return number += worker->number;
}
else
{
// return default value and/or make some output that cast failed
return -1;
}
}
为了避免dynamic_cast
运算符使用RTTI(运行时类型信息),不推荐使用,您可以在Person
中引入一个枚举,该枚举包含派生类的类型:
class Person
{
protected:
enum EPersonType {WORKER /*insert other derivats here*/};
const EPersonType Type;
Person(EPersonType type) : Type(type) {}
virtual int printDetails(Person* other) {}
public:
int print(Person* other)
{
if (other->Type != Type)
return -1;
else
return printDetails(other); // you can now use safe cast inhere
}
}
class Worker : public Person
{
public:
Worker() : Person(WORKER) {}
int printDetails(Person* other)
{
Worker* worker = static_cast<Worker*>(other); // always works
// also possible: ...= (Worker*)other;
//...
}
}
- 多态性和功能结合
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- C++boost序列化多态性问题
- 如何查找哪个类对象位于数组的特定索引上(多态性)
- 如何在多线程中正确使用unique_ptr进行多态性?
- 具有智能指针的多态性
- 在 C++ 中在堆栈上创建实例时如何保持多态性?
- 继承/多态性 - 我是否被迫使用"protected"变量?
- C++ 多态性在代码::块 17.12 中不起作用
- C++ 泛型和多态性:这种模式可行吗?
- 为什么我们实际上需要运行时多态性?
- 如何在这个简单的最小示例中实现多态性?
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 无法初始化已知大小的矢量指针,该大小不会因多态性而更改
- 运行时多态性和dynamic_cast需要澄清
- 如何调用指针类型的方法(禁用多态性)?
- 从基类调用函数的多态性
- 运行时多态性 - 箭头运算符访问了错误的成员?
- 为什么我在虚幻引擎中的多态性和接口方面遇到问题?