Существуют ли несколько функций-членов, скомпилированных для каждого объекта C++?
Я знаю, что когда мы создаем несколько объектов определенного типа, создаются несколько копий переменных-членов. Каждый объект имеет отдельный набор переменных-членов. Работает ли это так же с функциями-членами? Если в моем классе много функций, дублируются ли функции-члены для каждого создаваемого объекта? Каждый созданный объект имеет свой собственный набор функций-членов?
class demo {
public:
int height;
int width;
void setheight(int height)
{
this->height = height;
}
void getArea() const
{
return height * width;
}
// 100 more member functions.
};
Это всего лишь гипотетический пример, подтверждающий точку зрения о компиляторе C++. На самом деле это связано с тем, что я делаю в своем проекте. Предположим, у меня есть тип класса с несколькими переменными-членами, но с большим количеством функций-членов. Если я создам несколько объектов этого типа класса, будет ли у меня дублирование кода, при этом каждый объект будет иметь свою собственную копию функции-члена? В таком случае, было бы лучше для меня объявить функции как обычные автономные глобальные функции, которые вместо этого принимают объект в качестве параметра, чтобы избежать роста исполняемого файла?
1 ответ
Это просто деталь реализации (стандарт не требует ничего особенного), но практически все методы класса реализации по сути являются синтаксическим сахаром для "обычных", свободных функций, принимающих this
как скрытый параметр1. Итак, предложенная вами оптимизация - это то, что компилятор уже делает.
Для виртуальных методов задействованы некоторые дополнительные механизмы, поскольку каждый виртуальный метод обычно "стоит" один слот в виртуальной таблице класса (и всех его производных классов), но, опять же, это O(1), а не O(n) в количестве экземпляров.
- В некоторых реализациях есть также разница в соглашении о вызовах, например, в x86 VC++ методы получают
this
вecx
вместо того, чтобы в стеке, как это было бы, если бы это была свободная функция сthis
в качестве первого параметра, но это не имеет значения для нашего обсуждения.