Давайте возьмем следующий класс для примера
class Shape{
public:
Circle (int x): number(x){}
virtual area () {return x**2;}
private:
int number;
}
В основном мы создаем объекты
int main(){
Shape *foo = new Shape(8);
Shape *bar = new Shape(65);
Shape &obj1 = *foo, &obj2 = *bar;
}
Я считаю, что объекты 1 и 2 хранятся в куче. Это почему?
Как побочный вопрос. Влияет ли ключевое слово virtual и / или способ определения объектов (например, obj1 = * foo) на его расположение в памяти?
Существует (в широком смысле) два типа объектов W.R.T. управление их памятью:
Например, любой constexpr
Объект типа может быть полностью оценен и сконструирован во время компиляции и, как таковой, может быть помещен в сегмент данных памяти в качестве оптимизации (с точки зрения пуриста, это допустимо, но далеко не оптимально, для создания таких объектов во время выполнения. Но это приведет к потере циклов ЦП и увеличению продолжительности инициализации / запуска.
Вот несколько примеров таких объектов:
const char * const helloWorld = "Hello, world!";
struct TSilly{
TSilly(int _i = 0) : i(_i) {}
int i;
};
const TSilly silly1;
const TSilly silly2(42);
TSilly silly3; // doesn't have to be constexpr to qualify for static allocation.
// This one you can declare as /*extern TSilly silly3;*/ in
// header file and access from other compilation units
static TSilly silly4; // can be local to compilation unit, too
int main()
{
return 0;
}
Все остальные объекты должны будут ждать, пока будет построено время выполнения.
Примеры таких объектов:
const char * exeName1; // statically allocated by compiler
int main(int argc, char **argv)
{
exeName1 = argv[0]; // now points to a string
// buffer is allocated in free storage (heap) bu variable itself is on stack
char * exeName2 = new char[strlen(argv[0] + 1];
strcpy(exeName2, argv[0]); // now contains a COPY of a string
char exeName3[1024]; // likely allocated on stack, be careful with that as stack space is limited
strncpy(exeName3, argv[0], 1024); // will COPY at most 1023 characters from a string
delete [] exeName2; // don't forget to clean up
// exename3 will be auto-cleaned when we exit the function
return 0;
}
Как вы можете видеть, объект в C ++ будет помещен в сегмент данных или в свободное хранилище (кучу) в зависимости от его времени жизни.
Только динамически распределяется объекты гарантированно будут помещены в свободное хранилище. Я не думаю, что спецификация дает какие-либо обещания использования сегментов данных для статически распределенный Объекты — это зависит от компилятора, чтобы выполнить и использовать эту оптимизацию.
Для получения дополнительной информации посмотрите «Классы хранения C ++».
Есть много продвинутых тем управления памятью, которые вы, возможно, захотите изучить. Наиболее актуальным для этого обсуждения, вероятно, является на месте конструктор который позволяет вам иметь объект во время выполнения, построенный в памяти, выделенной в сегменте данных исполняемого файла.
Других решений пока нет …