C++ C+多态性+;
这是我的代码:C++ C+多态性+;,c++,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&
#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;
}
#包括
#包括
#包括
使用名称空间std;
班主任{
字符串名;
公众:
人员(常量字符串和n){
name=n;
}
虚拟人和打印(const person&){}
};
班主任:公众人士{
整数;
公众:
工作者(常量字符串&n,整数):个人(n){
number=num;
}
虚拟工作者和打印(常量工作者和x){
cout正如您已经注意到的,父类中的方法无法看到仅在其子类中定义的成员。如果您想一想,这很有意义,因为父类在编译时不可能知道其可能的子类是如何定义的,那么它如何知道其新的数据成员呢?
正确的方法是使Person
class中的print()
方法纯粹虚拟,并为每个子类编写一个单独的print()
方法,因为只有子类可以访问其私有数据成员
virtual void print() = 0;
请注意,该函数不再接受参数,它在子类中的实现应该打印它们自己的编号
,以及它们想要打印的任何其他成员。此代码非常奇怪。要打印,您不需要传入人员
或工作者
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;
}
班级人员
{
public:virtual void print(){cout您的两个print
函数在返回和参数类型上都不同。因此它们除了名称之外没有任何共同之处。此外,在运行时,计算机不知道哪种“种类”个人的
p
和q
是指向的。因此,您需要给打印
一个统一的签名,例如:
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;
}
}
这就是所谓的双重分派——同时在两个对象上执行多态性。如果使用worker
对象作为参数调用person
对象的打印函数,或者反过来调用worker
对象,您希望发生什么情况?OP希望基于参数打印()我看不出这对他的情况有什么帮助。这只会导致编译器错误,因为他无法实例化工人类,除非你也建议对其进行更改。@BenjaminLindley,看看答案的文本。我让他编写一个单独的print()
对于每个子类。您建议他给出什么签名?他已经为该子类编写了一个打印函数。问题是它的签名错误,因此不参与动态调度。但是如果他给出了正确的签名(以人员
而不是工作者
作为参数),函数不会编译,因为它访问person
类没有的成员。@BenjaminLindley,非常好的观点。我已经更新了答案。我认为他接受原始答案的原因是因为他在寻找如何设计它的想法,而不是特定的代码,这显然没有解决问题m、 我写这个答案时太匆忙了(
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;
}
}
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;
//...
}
}