2013-05-19 1 views
0

Ну, я использую карту для хранения любого указателя (void *), и он используется в объекте области видимости. вот класс области.Как получить данные без коррупции при использовании void *?

class Scope 
{ 
    protected: 
    Scope * parent; 
    MyMap* map; 
    public: 
    virtual void setParent(Scope* p)=0; 
    virtual Scope* getParent()=0; 
    virtual void setOwner(void * owner)=0; 
    virtual void * getOwner()=0; 
    virtual Symbol * get(char* name)=0; 
    virtual Symbol * get(char* name, Signature * sig)=0; 
    MyMap* getMap()const; 
}; 

и есть 2 класса OrderedScope и DisorderedScope которые реализуют Scope класс.

В моем проекте я пытаюсь хранить все данные как void *, а затем я извлекаю их и отсылаю их к соответствующему типу. когда я бросал объект по его типу, я обнаружил, что некоторые данные были потеряны. вот фотография того, что я получил. enter image description here

только для уточнения Package класс имеет сферу применения. И в этом объеме я храню объекты типа Function s. Поэтому, когда я хочу добавить к нему функцию, я должен сначала получить объект пакета, затем я могу использовать функцию add для вставки новой функции.

Я не знаю, правильно ли я показал проблему, но я надеюсь на это. Ваша помощь приветствуется.

+5

Почему бы не написать код, а не фотографию кода? Почему вы отметили это как 'yacc' - я не вижу ничего связанного с' yacc' в вашем вопросе? – user93353

+9

Любое решение, использующее 'void *' для хранения произвольных элементов, вероятно, будет подозрительным дизайном ... –

+0

Что такое «Карта»? Это как 'std :: map'? Почему вы храните 'void *' вместо хранения указателя на общий базовый класс и используете полиморфизм? – jamesdlin

ответ

2

Указатели Void являются рискованным механизмом, поскольку они отключают проверку типа компилятора для этого указателя. Поэтому, если вы допустили ошибку (например, листинг указателя void на неправильный тип), вы не получите ошибку времени компиляции, вы заметите проблему только как неправильное поведение во время выполнения, такое как повреждение данных.

Итак, чтобы ответить на вопрос: если вы хотите использовать указатели void и избегать повреждения данных, вам нужно очень точно убедиться, что, когда вы накладываете указатель на void (SomeType *), указатели void-pointer на самом деле содержат действительный (SomeType *) и ничего больше. В частности, вы должны убедиться, что указатель на ваш указатель на пустоты (SomeType *) остается действительным и не был удален/освобожден между временем создания указателя void и временем, которое вы пытаетесь выполнить, и используй это. Вы также должны знать о потенциальных проблемах, связанных с combining void pointers with multiple inheritance, поскольку класс с несколькими суперклассами может иметь другой «этот» указатель в зависимости от того, какой суперкласс вы просматриваете, а кастинг на указатель пустоты не будет автоматически сохранен правильный «этот» указатель для вас (поскольку компилятор не может знать, какой «этот» указатель вас интересует позже).

Это все выполнимо, но логика вашей программы должна быть на 100% правильной во всех случаях. Для этого нет ярлыка, кроме как очень тщательно закодировать все, изучить код, ищущий ошибки, и тщательно протестировать его. Code-checkers, такие как valgrind и Purify, также могут быть полезны при поиске ошибок, симптомы которых не всегда очевидны, просто запустив код.

Тем не менее, комментаторы, приведенные выше, являются правильными - обычно используются более/менее безопасные альтернативы использованию указателей void. Эти альтернативы (например, шаблоны и/или общий базовый класс) гораздо менее подвержены ошибкам, поскольку они позволяют компилятору обнаруживать ваши ошибки для вас во время компиляции, а не заставлять вас поочередно искать их во время выполнения , Кроме того, рассмотрите возможность использования интеллектуальных указателей (например, shared_ptr), а не сырых указателей, поскольку это приведет к выгрузке времени жизни объекта обработки в компилятор, который может справиться с этой задачей более надежно и последовательно, чем может быть обработан вручную.

 Смежные вопросы

  • Нет связанных вопросов^_^