2013-09-21 3 views
9

Как я могу указать указатель класса на общий указатель, например void *? Как этот код действителен ?,Указатель класса каста на указатель пустоты

class CFoo 
{ 
    int a; 
public: 
    CFoo():a(1){} 
    ~CFoo(){} 
    getNum(){return a;} 
}; 

void tfunc(void* data) 
{ 
    CFoo* foo = static_cast<CFoo*>(data); 
    std::cout << "Number: " << foo->getNum(); 
    delete foo; 
} 

int main() 
{ 
    CFoo* foo = new CFoo; 
    void* dt = static_cast<void*>(foo); 
    tfunc(dt); // or tfunc(static_cast<void*>(food)); 

    return 0; 
} 
+2

Последний раз, когда я читал «могу», я обещал сделать что-то ужасное, когда я встречу его в следующий раз. Жаль, что я не помню, что это было. Кроме того, вам даже не нужен бросок - можно назначить любой нефункциональный указатель на 'void *'. –

+0

Выглядит в порядке. [Прочитайте это] (http://stackoverflow.com/a/12275452/2089675) – smac89

+1

, если он скомпилирован, он действителен и IMO он должен скомпилировать. Но мне не нравится эта смесь C и C++ ... – alexbuisson

ответ

1

Является ли это действительное?

Да, он действителен в соответствии со стандартом § 5.2.9.7

prvalue типа «указатель на CV1 пустоты» может быть преобразовано в prvalue типа «указатель на CV2 Т», где T - тип объекта, а cv2 - это та же самая cv-квалификация, что и более высокая cv-квалификация, чем cv1. Значение нулевого указателя преобразуется в значение нулевого указателя для типа назначения. Значение указателя типа для объекта, преобразованного в «указатель на cv void» и обратно, возможно с другой cv-квалификацией, должно иметь свое первоначальное значение. [Пример:

T* p1 = new T; 
const T* p2 = static_cast<const T*>(static_cast<void*>(p1)); 
bool b = p1 == p2; // b will have the value true. 
8

Это вполне допустимо. Вот то, что стандарт должен сказать об этом:

§4.10 преобразования указателя

2 Rvalue типа «указатель на резюмеT,» где T является тип объекта , может быть преобразованный в rvalue типа "указатель на cv void." Результат преобразования «указатель на сортT» в «указатель к сортуvoid» указует на начало места хранения, где объекта типа T пребывает, как если объект является наиболее производным объект (1.8) типа T (то есть не подобъект базового класса).

означает, что вы можете преобразовать указатель класса пустой указатель. И ...

§5.2.9 Статическая отливать

10 An RValue типа "указатель на сортаvoid" может быть явно преобразован в указатель на объект типа. Значение указателя типа для объекта, преобразованного в «указатель на cvvoid» и обратно к исходному типу указателя .

означает, что вы можете использовать static_cast для преобразования пустого указателя обратно в исходном указатель класса.

Надеюсь, что это поможет. Удачи!

+0

Первая цитата говорит btw, что преобразование из типа указателя объекта в 'void *' может быть неявным (doesn ' t требуется литье). – dyp

+0

Какой стандарт/версия вы цитируете? Насколько я вижу, это не C++ 03 и C++ 11. – dyp

4

В C++ не нужен статический бросок, чтобы получить кvoid*:

int main() 
{ 
    CFoo* foo = new CFoo; 
    void* dt = foo; 
    tfunc(dt); // or tfunc(foo); 

    return 0; 
} 

NB: ваша реализация tfunc() совершенно правильно, что делает нужен бросок.

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