#c #pointers #types #void
#c #указатели #типы #пустота
Вопрос:
Я изучаю указатели на объекты. У меня есть этот код (комментарии в main отражают выходные данные для каждого оператора).
Foo сохраняет пустой указатель на объект и проверяет, являются ли другие указатели на этот объект либо самим объектом, либо ссылаются на тот же объект, на который указывает его сохраненный указатель.
При проверке объектов, на которые ссылается сохраненный указатель, он сначала приводит этот указатель к type bar.
В нескольких последних операторах он принимает пустой указатель на объект типа foo , приводит указатель на объект типа bar, а затем вызывает для него функцию, которая существует только в bar . Почему функция bar работает, когда объект имеет тип foo?
#include <iostream>
//#include <random>
//#include "sqlite3.h"
//#include "SDL.h"
//#include <cstdlib>
//#include <algorithm>
//#include <stdio.h>
using namespace std;
//int RunSqlNoCallback(sqlite3 * db, const char * zSql);
class bar
{
public:
bar()
{
x = 0;
}
void checkSelf(void* somePointer)
{
if (somePointer == this)
{
printf("bar it's me!n");
}
else
{
printf("bar It's not me.n");
}
}
void setx(int y)
{
x = y;
}
void checkx()
{
printf("This bar has x = %in",x);
}
private:
int x;
};
class foo
{
public:
void checkSelf(void* somePointer)
{
if (somePointer == this)
{
printf("foo it's me!n");
}
else
{
printf("foo It's not me.n");
}
}
void setsuch(void* someptr)
{
somesuch = someptr;
}
void checksuch(void* someptr)
{
bar* foobar = (bar*) (somesuch);
foobar->checkSelf(someptr);
}
void checksuchx()
{
bar *foobar = (bar*) (somesuch);
foobar->checkx();
}
private:
void* somesuch;
};
int main(int argc, char *argv[])
{
foo myfoo;
foo notmyfoo;
bar mybar;
mybar.checkx(); //this bar has x = 0
mybar.setx(5);
mybar.checkx(); //this bar has x = 5
foo* myfooptr = amp;myfoo;
bar* mybarptr = amp;mybar;
myfoo.checkSelf(myfooptr); //foo it's me
myfooptr = amp;notmyfoo;
myfoo.checkSelf(myfooptr); //foo it's not me
myfoo.checkSelf(mybarptr); //foo it's not me
myfooptr = amp;myfoo;
myfoo.checkSelf(myfooptr); //foo it's me
myfoo.setsuch(mybarptr);
myfoo.checksuch(mybarptr); //bar it's me
myfoo.checksuchx(); //this bar has 5
mybar.setx(7);
myfoo.checksuchx(); //this bar has 7
myfoo.checksuch(myfooptr); //bar it's not me
myfoo.setsuch(myfooptr);
//!This next line is the most confusing one. Why does it say "bar" in the output when foo has the same function "checkself" called by "checksuch"?
myfoo.checksuch(mybarptr); //bar it's not me
myfoo.checksuch(myfooptr); //bar it's not me
myfoo.checksuchx(); //this bar has x=8715752
system("PAUSE");
return 0;
}
Комментарии:
1. Вы используете термин «работа» в качестве замены «неопределенное поведение может привести к чему угодно» (даже к тому, что кажется, что «работает»).
2. Почему функция bar работает, когда объект имеет тип foo? — Потому что, используя приведение в стиле C, вы сказали компилятору «заткнись, это панель», а компилятор (и базовый код) сказал «хорошо, я тебе верю». То, что происходит после этого, может быть чем угодно. Если вы не применяли эти приведения, компилятор сообщит вам, выдав ошибку, что типы не совпадают.