为什么我的班级多态性失败(C++)
我想返回一个 struct ,它使用一个数字和一个对象,该对象是从 3个子类之一衍生的,该告诉该方法添加数字。我的思考过程是,使用运行时多态性,我可以过载该方法,并在3个变量中具有不同的子类的总和。但是,这似乎并没有发生,因为对象不会被降低到其子类。请记住,该程序事先不知道哪个子类将是结构,因此不可能手动铸造。
带有子类(SH)的类:
#pragma once
class Sugar{};
class Nincs : public Sugar
{
private:
static Nincs* ins;
Nincs(){};
public:
static Nincs* instance();
};
class Alfa : public Sugar
{
private:
static Alfa* ins;
Alfa(){};
public:
static Alfa* instance();
};
class Delta : public Sugar
{
private:
static Delta* ins;
Delta(){};
public:
static Delta* instance();
};
带子类(S.CPP)的类:
#include "s.h"
Nincs* Nincs::ins = nullptr;
Alfa* Alfa::ins = nullptr;
Delta* Delta::ins = nullptr;
Nincs* Nincs::instance()
{
if (ins == nullptr)
{
ins = new Nincs();
}
return ins;
};
Alfa* Alfa::instance()
{
if (ins == nullptr)
{
ins = new Alfa();
}
return ins;
}
Delta* Delta::instance()
{
if (ins == nullptr)
{
ins = new Delta();
}
return ins;
}
返回struct的类(现在只是NH,我计划将其分为.h and .cpp一旦解决了此问题):
#pragma once
#include "s.h"
struct Sugarzas
{
Sugar* fajta;
int mennyiseg;
};
class Noveny
{
protected:
std::string nev;
int tapanyag;
bool el_e;
public:
Noveny(std::string v1, int v2, bool v3): nev(v1), tapanyag(v2), el_e(v3){}
virtual Sugarzas ker(){};
};
class Puffancs : public Noveny
{
public:
Puffancs(std::string v1, int v2, bool v3): Noveny(v1,v2,v3){};
Sugarzas ker() override
{
Sugarzas s;
s.fajta = Alfa::instance();
s.mennyiseg = 10;
return s;
}
};
class Deltafa : public Noveny
{
public:
Deltafa(std::string v1, int v2, bool v3): Noveny(v1,v2,v3){};
Sugarzas ker() override
{
Sugarzas s;
s.fajta = Delta::instance();
if (tapanyag < 5)
{
s.mennyiseg = 4;
}
else if (tapanyag >=5 && tapanyag <=10)
{
s.mennyiseg = 1;
}
else
{
s.mennyiseg = 0;
}
return s;
}
};
class Parabokor : public Noveny
{
public:
Parabokor(std::string v1, int v2, bool v3): Noveny(v1,v2,v3){};
Sugarzas ker() override{}
};
具有功能的主文件:
#include <iostream>
#include "s.h"
#include "n.h"
using namespace std;
int sumNincs, sumAlfa, sumDelta;
void addTo(Nincs* s, int x)
{
sumNincs += x;
}
void addTo(Alfa* s, int x)
{
sumAlfa += x;
}
void addTo(Delta* s, int x)
{
sumDelta += x;
}
int main()
{
Puffancs* n = new Puffancs("bob",5,true);
sumNincs = 0;
sumAlfa = 0;
sumDelta = 0;
Sugarzas s = n->ker();
addTo(s.fajta,s.mennyiseg); //s.fajta comes out as Sugar* and does not get casted to the subclasses
return 0;
}
I want to return a struct which uses a number and one object deriving from one of 3 subclasses that tell the method where to add the number. My thought process is that using runtime polymorphism, I can overload the method and have the sum of different sub classes in 3 variables. However this doesn't seem to happen because the object doesn't get casted down to it's child class. Bear in mind, that the program doesn't know beforehand which subclass will be the struct, so manual casting is not possible.
The class with the subclasses (s.h):
#pragma once
class Sugar{};
class Nincs : public Sugar
{
private:
static Nincs* ins;
Nincs(){};
public:
static Nincs* instance();
};
class Alfa : public Sugar
{
private:
static Alfa* ins;
Alfa(){};
public:
static Alfa* instance();
};
class Delta : public Sugar
{
private:
static Delta* ins;
Delta(){};
public:
static Delta* instance();
};
The class with the subclasses (s.cpp):
#include "s.h"
Nincs* Nincs::ins = nullptr;
Alfa* Alfa::ins = nullptr;
Delta* Delta::ins = nullptr;
Nincs* Nincs::instance()
{
if (ins == nullptr)
{
ins = new Nincs();
}
return ins;
};
Alfa* Alfa::instance()
{
if (ins == nullptr)
{
ins = new Alfa();
}
return ins;
}
Delta* Delta::instance()
{
if (ins == nullptr)
{
ins = new Delta();
}
return ins;
}
The classes that return the struct (this is only n.h for now, I plan to separate it into .h and .cpp once this issue is resolved):
#pragma once
#include "s.h"
struct Sugarzas
{
Sugar* fajta;
int mennyiseg;
};
class Noveny
{
protected:
std::string nev;
int tapanyag;
bool el_e;
public:
Noveny(std::string v1, int v2, bool v3): nev(v1), tapanyag(v2), el_e(v3){}
virtual Sugarzas ker(){};
};
class Puffancs : public Noveny
{
public:
Puffancs(std::string v1, int v2, bool v3): Noveny(v1,v2,v3){};
Sugarzas ker() override
{
Sugarzas s;
s.fajta = Alfa::instance();
s.mennyiseg = 10;
return s;
}
};
class Deltafa : public Noveny
{
public:
Deltafa(std::string v1, int v2, bool v3): Noveny(v1,v2,v3){};
Sugarzas ker() override
{
Sugarzas s;
s.fajta = Delta::instance();
if (tapanyag < 5)
{
s.mennyiseg = 4;
}
else if (tapanyag >=5 && tapanyag <=10)
{
s.mennyiseg = 1;
}
else
{
s.mennyiseg = 0;
}
return s;
}
};
class Parabokor : public Noveny
{
public:
Parabokor(std::string v1, int v2, bool v3): Noveny(v1,v2,v3){};
Sugarzas ker() override{}
};
main file with the functions:
#include <iostream>
#include "s.h"
#include "n.h"
using namespace std;
int sumNincs, sumAlfa, sumDelta;
void addTo(Nincs* s, int x)
{
sumNincs += x;
}
void addTo(Alfa* s, int x)
{
sumAlfa += x;
}
void addTo(Delta* s, int x)
{
sumDelta += x;
}
int main()
{
Puffancs* n = new Puffancs("bob",5,true);
sumNincs = 0;
sumAlfa = 0;
sumDelta = 0;
Sugarzas s = n->ker();
addTo(s.fajta,s.mennyiseg); //s.fajta comes out as Sugar* and does not get casted to the subclasses
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来功能超载与功能覆盖之间存在一些混乱。虚拟函数可以被覆盖,其中基类中定义的成员函数可以被派生类中具有相同签名*的成员函数覆盖,然后将调用对基类方法的调用基于实际派生的对象最多的运行时类,该方法正在调用。
*除了可能具有协变返回类型。
但是,您的
addto
功能不是覆盖的情况。它们是超负荷的情况,您的功能具有相同的名称,但签名不同。必须在编译时解决过载分辨率。s.fajta的静态类型
是sugar*
,即使实际指向对象是alfa
。如果您想拥有取决于
*s.fajta
的混凝土类型的行为,则需要Sugar
类具有虚拟方法。由于我不清楚这里应该发生什么,因此我不确定如何重组您的程序以使用此行为。It looks like there's some confusion between function overloading and function overriding. Virtual functions can be overridden, where a member function defined in a base class can be overridden by a member function with the same signature* in a derived class, and then calls to the base class method will be dispatched based on the actual runtime most derived class of the object the methods are being called on.
*Except possibly having a covariant return type.
However, your
addTo
functions are not a case of overriding. They are a case of overloading, where you have functions with the same name but different signatures. Overload resolution must be resolved at compile time. The static type ofs.fajta
isSugar*
, even though the actual pointed-to object is anAlfa
.You'd need your
Sugar
class to have virtual methods if you want to be able to have behavior that depends on the concrete type of*s.fajta
. Since I'm not clear on what exactly is supposed to be happening here, I'm not sure how to restructure your program to use this behavior.