在C++中使用多态时,了解它的重要事实是什么.
比如,例如,从何时derived开始base,应该注意什么?
什么时候可以上线,什么时候不可以?你什么时候需要一个'虚拟'析构函数?什么时候不需要?
使用从base到派生对象的指针时需要注意什么?
有一个在C++休息室讨论刚才关于sizeof(*this)同态的类型,这启发了我问这个问题.
像这样一个"模糊"的事实:
"如果你有一个隐藏在Base&后面的Derived,那么静态类型是Base,而动态类型是Derived."
在这个问题上,也是我正在寻找的东西.
我想比较两个派生自相同基类型但不是相同派生类的对象.所以我将==运算符设为虚拟并在派生类中覆盖它.
当我将所有对象存储在基类型的数组中时,不会调用派生的实现,而是直接进入基本实现.但是,当数组是指向基类的类型指针并且取消引用元素时,它确实有效.
请问一些人请解释为什么会出现这种情况?它让我困惑;-)
enum eType {
BASE_TYPE,
DERIVED_TYPE
};
class A {
eType mType;
public:
A() : mType(BASE_TYPE) {}
A(eType Type) : mType(Type) {}
virtual bool operator == (A &Other) {
return mType == Other.mType;
}
};
class B : public A {
int bVal;
public:
B(int Val) : A(DERIVED_TYPE), bVal(Val) {}
virtual bool operator == (A &Other) {
if(!(A::operator ==(Other))) {
return false;
}
B* myB = (B*)&Other;
return bVal == myB->bVal;
}
};
int main(int argc, char *argv[]) …Run Code Online (Sandbox Code Playgroud) 我在获取std list类以调用类上的正确函数时遇到了麻烦.它一直只调用基类的函数.这是发生了什么:
我有一个具有以下更新功能的状态类,在头中声明为虚拟:
State.h更新功能:
virtual void update(float elapsed);
Run Code Online (Sandbox Code Playgroud)
State.cpp更新功能:
void State::update(float elapsed){
};
Run Code Online (Sandbox Code Playgroud)
以及从它继承的一个名为TestState的类:
class TestState::public State{
virtual void update(float elapsed){
if (GLOBALENGINE->getInput() -> getKeyPress(DIK_Q)
PostQuitMessage(0);
};
};
Run Code Online (Sandbox Code Playgroud)
我调用addState函数将新状态添加到链表并使其成为当前状态,如下所示:
GLOBALENGINE->addState(new TestState,true);
Run Code Online (Sandbox Code Playgroud)
addState函数如下所示:
void GameEngine::addState(State *state, bool change){
states->push_back(*state); //add the test state into the states list
// some irrelevant code
currentState = &(states->back());//currentState is a pointer to a State
// So we make it point to the newly added state.
}
Run Code Online (Sandbox Code Playgroud)
然后每帧调用run()函数,其内部是以下代码:
currentState->update(elapsed)// This should call the update function in …Run Code Online (Sandbox Code Playgroud) 我想知道为什么静态对象在这个例子中调用父方法和动态对象子方法.
#include <string>
#include <iostream>
using namespace std;
class Father {
public:
virtual string Info() {
return "I am father";
}
};
class Son : public Father {
public:
string Info() {
return "I am son";
}
};
int main() {
Father f = Son();
cout << f.Info(); // I am father
Father* pf = new Son();
cout << pf->Info(); // I am son
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我有这两个类:
class A
{
public:
A();
virtual ~A();
virtual void TellMyName();
};
class B : public A
{
private:
std::string szName;
public:
B();
~B();
void TellMyName();
void SetName(std::string val){ szName = val; }
};
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
void main()
{
std::vector<A*> List_A;
B* B_Instance = new B();
B_Instance->SetName("B");
List_A.push_back(B_Instance); // Way 1
List_A.push_back(new A((*B_Instance))); // Way 2
List_A[0]->TellMyName();
List_A[1]->TellMyName();
}
Run Code Online (Sandbox Code Playgroud)
TellMyName()就是要提示一个消息框.如果我使用"方式1"它没有问题,但如果我使用"方式2"它将提示没有文本的消息,这意味着B类的所有成员都是空的,就像他们从来没有被任何东西填满.我通过使用解决了这个问题std::shared_ptr,但是有没有其他方法可以不使用智能指针,因为我必须在一个大项目中实现这种方法,并且会有很多变化和失败.顺便说一下,"Way 2"的原因是什么?
有人可以解释为什么i->value()和(i + 1)->value()打印1和3不是1和4喜欢 x[0]->value() << x[1]->value()
#include <iostream>
#include <vector>
class A
{
public:
A(int n = 0) : m_n(n) { }
public:
virtual int value() const { return m_n; }
virtual ~A() { }
protected:
int m_n;
};
class B
: public A
{
public:
B(int n = 0) : A(n) { }
public:
virtual int value() const { return m_n + 1; }
};
int main()
{
const A a(1); //a.m_n=1
const B b(3); …Run Code Online (Sandbox Code Playgroud) 我在命名空间中有一个全局函数,这个函数是一个辅助函数,它将创建对象并返回它们.但是返回类型是父类,但返回的实际对象是父类的子类.然后由用户将其返回"父"对象强制转换为适当的子类.我认为这是多态性的,但我无法将返回的对象强制转换为子类.例如:
class Parent {...};
class ChildOne : public Parent {...};
class ChildTwo : public Parent {...};
Parent my_function(int x) {
if(x) {
return ChildOne();
}
else {
return ChildTwo();
}
};
int main() {
// The statement below is giving me an error (no matching function call...)
ChildOne my_child = (ChildOne)my_function(1);
}
Run Code Online (Sandbox Code Playgroud) 比如说你有:
class Plant {
public:
...public accessors, etc ...
}
Run Code Online (Sandbox Code Playgroud)
然后你有一个特定的植物类:
class Broccoli : public Plant
{
public:
Broccoli(int i);
virtual ~Broccoli();
inline BroccoliSprite* getPlantSprite() { return _plantSprite; };
private:
BroccoliSprite* _plantSprite;
};
Run Code Online (Sandbox Code Playgroud)
在某些时候,Broccoli对象存储在向量中:std::vector<Plant> vPlants;
访问我使用的向量及其元素: inline std::vector<Plant>& getPlants() { return vPlants; };
访问:
for (int f=0; f < _f.getPlants().size(); f++)
{
Plant _p1 = _f.getPlants().at(f);
cocos2d::CCSprite* s = _p1.getPlantSprite();
....
}
Run Code Online (Sandbox Code Playgroud)
我希望能够用getPlantSprite()它来显示给用户,但编译器告诉我:No member named 'getPlantSprite' in 'Plant'
这是真的,但是向量中的对象是类型Plant并且包含一个成员变量,它是我需要的精灵,getter返回它.
我不明白的是如何获得访问权限 getPlantSprite()
我想有一点是我可以改变 …
AoA,我正在制作一个国际象棋的控制台游戏,但我坚持多态,下面是类和函数定义/*旧的部分//基类
class Piece /*Parent class */
{
protected:
Position* pCoord;
std::string color;
char symbol;
public:
Piece(Position* Coord,std::string Color,char symbol);
Position GetCurrentPos();
std::string GetColor();
void SetColor(std::string color);
void Draw();
virtual bool SetPos(Position* newPos){MessageBox(NULL,L"Virtual Running",L"Error",MB_OK); return true;};
virtual ~Piece();
};
/* Inherited classes */
//Child classes
class Pawn: public Piece
{
private:
std::vector<Position>* allowPos;
public:
Pawn(Position* Coord,std::string Color,char symbol);
~Pawn();
std::vector<Position>* GetThreatendFields();
bool isValidMove(Position* newPos);
bool SetPos(Position* newPos);
};
//Child classes
class Bishops: public Piece
{
private:
std::vector<Position>* allowPos;
public:
Bishops(Position* Coord,std::string …Run Code Online (Sandbox Code Playgroud) 我有来自第三方库的两个结构,所以我不能改变它们的布局.但是我有两个我自己编写的结构符合它们的签名,所以我可以为它们添加函数(再次,但不是它们的布局,因此也没有虚函数).结构被称为Foo1和Foo2.两者都有相同的成员调用_b,但是在不同的偏移量.
struct FooBase { };
struct Foo1 : FooBase
{
int _a = 2;
int _b = 1;
};
struct Foo2 : FooBase
{
int _b = 2;
};
struct Wrap
{
Wrap(const FooBase& x) : _x(x) { }
FooBase& _x;
int GetValue() { return /* MISSING */; }
};
Run Code Online (Sandbox Code Playgroud)
我有一个名为的包装类Wrap.我正在寻找一种方法来返回_bfoo类中不使用虚函数的值,因为我不能再改变它们的大小了.
Foo1 f1 = Foo1();
Wrap x = f1;
int a = x.GetValue(); // should return 1
Foo2 …Run Code Online (Sandbox Code Playgroud)