Pergunta

Example

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>

struct father
{
    int variable;
    father(){variable=0xEEEEEEEE;};
    virtual void sing(){printf("trollolo,%x\n",variable);}
    ~father(){};
};
struct son:father
{
    son(){variable=0xDDDDDDDD;};
    virtual void sing(){printf("trillili,%x\n",variable);}
    ~son(){};
};
int main()
{
    father * ifather=new(father);
    son * ison=new(son);
    father uncle;
    father * iteachers;

    *((long long*)&uncle)=0xDEAF;
    iteachers=(father*)malloc(20*sizeof(father));

    //ineffective assignments
    iteachers[0]=*ifather;
    uncle=*ifather;

    ifather->sing();//called to prevent optimization
    ison->sing();//only to prevent optimization

    std::cout.setf(std::ios::hex);
    std::cout<<"father:"<<*((long long*)ifather)<<","<<std::endl;
    std::cout<<"teacher0:"<<*((long long*)&(iteachers[0]))<<","<<std::endl;
    std::cout<<"uncle:"<<*((long long*)&uncle)<<","<<std::endl;
    std::cout<<"(son:"<<*((long long*)ison)<<"),"<<std::endl;

//  uncle.sing();//would crash
}

The vtable pointer of teachers[0] is zero when compiled with gcc. Also the vtable pointer of uncle keeps its original value instead of being overwritten. My questions: Why HAS it be that way? Is there a CLEAN workaround? Can i go with uncle._vptr=ifather->_vptr and still be portable? What is the ORDINARY routine to copy an object? Should I even file a bug? Note: it should copy the whole object platform-independant, because no matter how the identification of the object type is done, since it should always be inside the object's data block!

The article

Why does my C++ object loses its VPTr

didn't help me, that must have a different reason.

Foi útil?

Solução

As I understand it, basically the question is whether this code:

#include <iostream>
using namespace std;

struct Base
{
    virtual void sing() { cout << "Base!" << endl; }
    virtual ~Base() {}
};

struct Derived: Base
{
    void sing() override { cout << "Derived!" << endl; }
};

auto main()
    -> int
{
    Base* p = new Derived();
    *p = Base();
    p->sing();      // Reporting "Base" or "Derived"?
}

should report "Base" or "Derived".

In short, assignment does not change the type of an object.

Hence, it reports "Derived".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top