2010-05-07 2 views
-1
class A 
{ 
public: 
int i; 
int j; 

}; 

class B : public A 
{ 
public: 
int k; 

}; 

main() 
{ 
    A *a = new B; 

} 

Можно ли получить доступ к данным нарезки?Как получить доступ к разрезанию объектов?

+4

здесь нет объекта нарезки. Можете быть более конкретными? что подразумевается под * доступом к * срезу объектов? – Naveen

+1

См. Http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c для хорошего обсуждения этого вопроса. –

+0

@Naveen: Но если вы, как программист, не заметите, помните что это B, нет никакого способа узнать, что '* a' также содержит B-часть, поэтому он так же хорош, как нарезанный. – UncleBens

ответ

1

Нарезка выглядит следующим образом:

struct B { 
    virtual ~B() { } 
}; 
struct D : public B { 
    int a, b; 
}; 

int main() 
{ 
    D der; 
    B bas(der); // der is sliced! 
} 

Там нет никакого способа для B bas объекта, чтобы увидеть дополнительную информацию D der даже если информация есть. Мы говорим, что эта дополнительная информация «отрезана». bas не может получить доступ к каким-либо из них, потому что стандарт позволяет D объекты, которые должны храниться в памяти (почти) произвольно, для целей alignment. Единственная гарантия, которую вы имеете на der, заключается в том, что ее первый адрес члена данных совпадает с адресом объекта.

0

Я считаю, что ответ заключается в том, чтобы сбрасывать указатель.

static_cast<B*>(a)->k = 10; 

Предпосылкой является то, что вы на самом деле знать наверняка, что на данный момент в коде a всегда относится к экземпляру B, потому что, из-за отсутствия виртуальных функций и виртуальные таблицы, нет никакой возможности для язык для тестирования во время выполнения, если это действие действует или нет.


Технически, ничего не разрезается еще, вы просто не можете получить доступ к нему иначе, потому что для всех компилятор знает, у вас есть указатель на объект типа А, и это тот случай, когда вы просто должны знать, лучше.


ИМО, если вы только использовать наследование для добавления полей данных в классе, который существует только для хранения данных, вы не должны вообще быть баловаться с указателями на базовый класс на всех.

Если вы показываете только часть кода, и у вас есть виртуальные функции, используйте вместо этого dynamic_cast, потому что тогда можно проверить, действителен ли актер.