2016-08-13 130 views
2

我想做一个父子元素的向量。我只用一个孩子测试了我的代码,这很好。但是当我添加一个孩子(Child2)时,我看到一个问题。
当我尝试获得值px预期的输出是:5 7 11,但我得到的值为type variable(2);父母和孩子的向量C++

Main.cpp的

#include <SFML/Graphics.hpp> 
#include "Helper.h" 
#include <vector> 
#include <iostream> 
using namespace sf; 

int main() { 
    std::vector<Parent*> arr1; 
    arr1.push_back(new Child(3, 4, 5, 6)); 
    arr1.push_back(new Parent(7, 8)); 
    arr1.push_back(new Child2(9, 10, 11, 12)); 

    std::cout << static_cast<Universal*>(arr1.at(0))->dx << std::endl; 
    std::cout << static_cast<Universal*>(arr1.at(1))->x << std::endl; 
    std::cout << static_cast<Universal*>(arr1.at(2))->px << std::endl; 
    return 0; 
} 

Helper.cpp

#include "Helper.h" 

Parent::Parent(int x, int y) { 
    this->x = x; 
    this->y = y; 
} 

Child::Child(int x, int y, int dx, int dy) : Parent(x, y) { 
    this->dx = dx; 
    this->dy = dy; 
} 

Child2::Child2(int x, int y, int px, int py) : Parent(x, y) { 
    this->px = px; 
    this->py = py; 
} 

Universal::Universal(int x, int y) : Parent(x, y) {} 

Helper.h

class Parent { 
public: 
    int x, y; 
    int type = 0; 

    Parent(int x, int y); 
}; 

class Child : public Parent { 
public: 
    int dx, dy; 
    int type = 1; 

    Child(int x, int y, int dx, int dy); 
}; 

class Child2 : public Parent { 
public: 
    int px, py; 
    int type = 2; 

    Child2(int x, int y, int px, int py); 
}; 

class Universal : public Parent { 
public: 
    int dx, dy, px, py; 

    Universal(int x, int y); 
}; 
+3

你有UB和你的'static_cast '。 – Jarod42

+1

将原始指针存储在'std :: vector'(或任何STL容器)中几乎总是一个坏主意。改为使用'std :: vector >'。 – ArchbishopOfBanterbury

+0

@ Jarod42,什么是UB? –

回答

2

Universal不是父母或子女Child2。因此,static_cast将不起作用。

CHILD2有以下类成员:

int int int 
px  py type 

通用,在另一方面,包含以下类成员:

int int int int 
dx  dy px  py 

这就是为什么当代码读取px,它结束了得到的值为type。您的编译器只需将每个类成员连续放置为其类的一部分,而不考虑类成员的名称。 type在其中一个类中最终占据相同的相对位置,从类的开头开始,在内存中的偏移量为px。这些类包含int类成员。 type是其中一个类别中的第三个int,并且type是另一个中的第三个int

仅仅因为两个类有一个具有相同名称的类成员,并不意味着类成员在内存中将具有与其类的成员相同的内部位置。

实际上,C++标准并没有给你很多保证。无论如何,无法保证班级成员将以任何特定的顺序安排在记忆中。实际上有一些规则,但它们与此问题的目的无关。

即使两个类都列出了它们的字段,但在类声明中,按照某种特定的顺序,不应该最终依赖于这样一个事实:一个非常粗鲁的static_cast将以不同的类结束,并且具有相同的字段名称与其他类具有相同的值。

正在尝试做的解决方案是使用virtual类方法。

+0

谢谢!我创建了虚拟方法getDX,DY,PX,PY,getType并解决了我的问题。 –