Приведение к void*
От: mPronin  
Дата: 08.09.09 15:45
Оценка:
Насколько законно такое приведение типов.
class A
{
public:
    virtual void method();
};

class B
{
public:
    virtual void method2();
};

class C :  public A, public B
{
public:
    virtual void method();
    virtual void method2();
};

int main(int argc, char* argv[])
{
    C * c = new C;
    void * p = (A*)c;

    A * a = (A*)p;
    a->method();

    return 0;
}
Re: Приведение к void*
От: D14  
Дата: 08.09.09 16:08
Оценка:
Здравствуйте, mPronin, Вы писали:

P>Насколько законно такое приведение типов.


Загони текст в http://www.comeaucomputing.com/tryitout/ и не парься.
Re[2]: Приведение к void*
От: mPronin  
Дата: 08.09.09 16:37
Оценка:
Здравствуйте, D14, Вы писали:

D14>Загони текст в http://www.comeaucomputing.com/tryitout/ и не парься.


То что этот код компилируется я и так знаю, вопрос в том будет ли он работать как предполагается.
Re[3]: Приведение к void*
От: Programador  
Дата: 08.09.09 16:45
Оценка:
Здравствуйте, mPronin, Вы писали:

P>То что этот код компилируется я и так знаю, вопрос в том будет ли он работать как предполагается.

void* и обратно стандарт гарантирует
Re: Приведение к void*
От: Николай Ивченков  
Дата: 08.09.09 17:03
Оценка: 3 (1)
Здравствуйте, mPronin, Вы писали:

P>Насколько законно такое приведение типов.


Законно. Вот как описывается твоё явное преобразование к A*:

5.4/5:

The conversions performed by
— a const_cast (5.2.11),
a static_cast (5.2.9),
— a static_cast followed by a const_cast,
a reinterpret_cast (5.2.10), or
— a reinterpret_cast followed by a const_cast,
can be performed using the cast notation of explicit type conversion. The same semantic restrictions and behaviors apply. If a conversion can be interpreted in more than one of the ways listed above, the interpretation that appears first in the list is used, even if a cast resulting from that interpretation is ill-formed. If a conversion can be interpreted in more than one way as a static_cast followed by a const_cast, the conversion is ill-formed.

5.2.9/2:

An expression e can be explicitly converted to a type T using a static_cast of the form static_cast<T>(e) if the declaration “T t(e);” is well-formed, for some invented temporary variable t (8.5). The effect of such an explicit conversion is the same as performing the declaration and initialization and then using the temporary variable as the result of the conversion.

8.5/14:

The semantics of initializers are as follows. [...]
— If the destination type is a reference type, see 8.5.3.
— If the destination type is an array of characters or an array of wchar_t, and the initializer is a string literal,
see 8.5.2.
— Otherwise, if the destination type is an array, see 8.5.1.
— If the destination type is a (possibly cv-qualified) class type:[...]
— Otherwise, if the source type is a (possibly cv-qualified) class type, conversion functions are considered.[...]
Otherwise, the initial value of the object being initialized is the (possibly converted) value of the initializer expression. Standard conversions (clause 4) will be used, if necessary, to convert the initializer expression to the cv-unqualified version of the destination type; no user-defined conversions are considered. If the conversion cannot be done, the initialization is ill-formed.

4.10/3:

An rvalue of type “pointer to cv D,” where D is a class type, can be converted to an rvalue of type “pointer to cv B,” where B is a base class (clause 10) of D. If B is an inaccessible (clause 11) or ambiguous (10.2) base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion is a pointer to the base class sub-object of the derived class object. The null pointer value is converted to the null pointer value of the destination type.

Далее у тебя следует неявное преобразование к void* —

см. 8.5/14 и
4.10/2:

An rvalue of type “pointer to cv T,” where T is an object type, can be converted to an rvalue of type “pointer to cv void.” The result of converting a “pointer to cv T” to a “pointer to cv void” points to the start of the storage location where the object of type T resides, as if the object is a most derived object (1.8) of type T (that is, not a base class subobject).

После ты выполняешь обратное преобразование к A* —

см. 5.4/5 и
5.2.9/10:

An rvalue of type “pointer to cv1 void” can be converted to an rvalue of type “pointer to cv2 T,” where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. A value of type pointer to object converted to “pointer to cv void” and back to the original pointer type will have its original value.

Итого результирующий указатель указывает на базовый подобъект типа A внутри C.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.