我已经用各自的数据成员编写了Base类和Derived类,如下面的代码所示。现在在主函数中,我使用static_cast创建了由Derived类指针指向的新Base类对象。
#include <iostream>
#include <vector>
class Base {
public:
int b;
Base() : b(2){};
int get_b() const;
};
class Derived : public Base {
public:
int d;
Derived() : d(4){};
int get_d() const;
};
int Base::get_b() const { return b; }
int Derived::get_d() const { return d; }
int main() {
std::vector<Derived *> bArray;
bArray.push_back(static_cast<const Derived *>(new Base()));
bArray.push_back(static_cast<const Derived *>(new Base()));
std::vector<Derived *>::iterator bArrayIt = bArray.begin();
for (; bArrayIt != bArray.end(); ++bArrayIt) {
std::cout << (*bArrayIt)->get_b() << std::endl;
std::cout << (*bArrayIt)->get_d() << std::endl;
}
}
输出:
2
0
现在在代码中,我尝试使用Derived指针访问derived类的数据成员,但我希望它返回编译错误或'ArrayOutOfBoundIndex'或segmentation_fault,因为对象是< [Base type,因为仅为基础对象分配了空间,但是该成员'd'的值为零。根据我对static_cast的了解,它只是更改指针类型而不分配内存,但是在这里,我们不仅可以访问未分配的内存,而且该值最初已预先设置为0,所以我做了一个小实验我自己的。
#include <iostream>
#include <string.h>
class State;
class Base;
class Derived;
class State {
public:
static bool flag;
};
bool State::flag = true;
class Base : public State {
public:
int a;
int b;
int c;
Base() : a(2), b(4), c(16){};
int get_a() { return a; }
int get_b() { return b; }
int get_c() { return c; }
};
class Derived : public Base {
public:
int d;
int e;
int f;
Derived() : d(6), e(8), f(12){};
int set_d(int ds) { d = ds; }
int get_d() { return d; }
int get_e() { return e; }
int get_f() { return f; }
};
int main() {
Derived *d[2];
d[0] = static_cast<Derived *>(new Base());
d[1] = static_cast<Derived *>(new Base());
std::cout << d[0]->get_a() << std::endl;
std::cout << d[0]->get_d() << std::endl;
d[0]->set_d(100);
std::cout << d[0]->get_d() << std::endl;
int *i = reinterpret_cast<int *>(d[0]);
std::cout << (*i) << std::endl;
i++;
std::cout << (*i) << std::endl;
i++;
std::cout << (*i) << std::endl;
i++;
std::cout << (*i) << std::endl;
i++;
std::cout << (*i) << std::endl;
i++;
std::cout << (*i) << std::endl;
std::cout << "Let's move onto d[1]" << std::endl;
int *j = reinterpret_cast<int *>(d[1]);
std::cout << (*j) << std::endl;
j++;
std::cout << (*j) << std::endl;
j++;
std::cout << (*j) << std::endl;
j++;
std::cout << (*j) << std::endl;
j++;
std::cout << (*j) << std::endl;
j++;
std::cout << (*j) << std::endl;
return 0;
}
:输出
2
0
100
2
4
16
100
0
0
Let's move into d[1]
2
4
16
0
0
0
输出是根据我之前得到的。:我的问题
std::vector<Derived *> bArray;
bArray.push_back(static_cast<const Derived *>(new Base()));
在上面的代码中,您创建了一个Derived类型的向量,然后创建Base类型,并告诉编译器“好像它是派生类型”一样插入它。此时,成员os派生类型尚未定义,因此事实>>
std::cout << (*bArrayIt)->get_d() << std::endl;
返回0是您的运气(或运气不好)。当您访问RAM中靠近程序的内存时,您可能不会破坏任何内容,但是正如其他人指出的那样,这是UB。编译器不会阻止您这样做,因为这将需要一些运行时检查(这会使程序变慢),并且您可能会或可能不想使用(不支付不使用规则)[]