malloc으로 할당 된 객체에 vtable 포인터를 설정하는 컴파일러 독립적이고 구문 적으로 우아한 방법이 있습니까?VTable 포인터 및 malloc에
방출을위한 충분한 시간이있을 때까지 메모리 관리자에서 메모리 위치를 유지하기 위해 void ptrs를 사용해야하는 필요에 따라 메모리 릴리즈의 흐름을 제어 할 수 있어야하므로 새로운 기능을 직접 사용할 수는 없습니다.
class AbstractData
{
public:
AbstractData() {}
virtual ~AbstractData() {}
protected:
virtual void SetData(int NewData) =0;
virtual int GetData() const =0;
};
class ConcreteData : public AbstractData
{
protected:
int Data;
public:
ConcreteData() {}
~ConcreteData() {}
void SetData(int NewData);
int GetData() const;
};
void ConcreteData::SetData(int NewData) {Data=NewData;}
int ConcreteData::GetData() const
{return Data;}
int main(int argc, char* argv[])
{
int OBJ_NUMBER = 4;
ConcreteData* Test = (ConcreteData*)malloc(OBJ_NUMBER*sizeof(ConcreteData));
if (!Test)
return -1;
for (int x = 0; x < OBJ_NUMBER; x++)
Test[x] = ConcreteData();
Test[0]->GetData(); //Constructor was never called, vptr never initialized, crash
free(Test);
Test = NULL;
}
로컬 복사본에 초기화 된 vtable 포인터가 있기를 기대했지만 실제로는 그렇지 않습니다. 어디 있는지 알고 있다면 vptr의 오프셋에 대한 컴파일러 종속적 인 역 참조를 할 수 있다는 것을 알고 있지만이 솔루션은 컴파일러에 의존하고 많은 할당에서 사용하기에는 좋지 않습니다. 예 ++ 8.0
int main(int argc, char* argv[])
{
int OBJ_NUMBER = 4;
ConcreteData* Test = (ConcreteData*)malloc(OBJ_NUMBER*sizeof(ConcreteData));
if (!Test)
return -1;
ConcreteData StealVPtr();
int* VPtr = *(int**)StealVPtr;
for (int x = 0; x < OBJ_NUMBER; x++)
*(int**)Test[x] = VPtr;
Test[0]->GetData(); //VPtr initialized in compiler dependent way
free(Test);
Test = NULL;
}
또는 MSVC와 함께 작동, 배치 새가 사용될 수 있지만, 다시 한번 구문이 우아 모양과 배열이 PTR 앞에 계산 추가 할 때 배열 소멸자와 유형의 문제를 상쇄가 발생할 수 있습니다.
int main(int argc, char* argv[])
{
int OBJ_NUMBER = 4;
ConcreteData* Test = (ConcreteData*)malloc(OBJ_NUMBER*sizeof(ConcreteData));
if (!Test)
return -1;
for (int x = 0; x < OBJ_NUMBER; x++)
{
if (!(ConcreteData* PlcTest = new(Test[x]) ConcreteData()))
{
free(Test);
Test = NULL;
return -1;
}
}
PlcTest[0]->GetData(); //Constructor was invoked and VPtr was initialized
for (int x = OBJ_NUMBER-1; x >= 0; x--)
PlcTest[x].~ConcreteData();
PlcTest = NULL;
free(Test);
Test = NULL;
}
정말이게 malloc을 사용하는 객체에서 VTable ptr/call 생성자를 초기화하는 유일한 방법입니까?
새 소리가 좋은 옵션입니다. 아마 당신은이 전략에 당신을 인도 한 것에 다시 한번 주목할 필요가 있습니다. –
그것은 "WTF ??!?"라고 말하는 가장 좋고 정치적인 방법이어야합니다. 나중에 사용하기 위해 주목! –
'c'태그가 지정 되었습니까? C는 새로운 클래스, 클래스, 퍼블릭, 가상 또는 보호 된, 또는 생성자 또는 소멸자에 대한 개념이 없다. 'malloc', ..., ...의 반환 값에 대한 캐스트가 필요하지 않습니다. – pmg