Как Вы определяете размер объекта в C++?

Что касается @Stunner, это мой вклад в достижение цели. Я что-то изменил и добавил свойство _previousSelectedSegmentIndex; в коде @Stunner переменная previousSelectedSegmentIndex оказалась бесполезной:

@implementation STASegmentedControl
{
    NSInteger _previousSelectedSegmentIndex;
}

- (void)setSelectedSegmentIndex:(NSInteger)selectedSegmentIndex
{
    [super setSelectedSegmentIndex: selectedSegmentIndex];

    _previousSelectedSegmentIndex = self.selectedSegmentIndex;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];

    CGPoint locationPoint = [[touches anyObject] locationInView:self];
    CGPoint viewPoint = [self convertPoint:locationPoint fromView:self];
    if (self.toggleableSegments) { // toggle selected segment on/off
        if ([self pointInside:viewPoint withEvent:event] && _previousSelectedSegmentIndex == self.selectedSegmentIndex) {
            self.selectedSegmentIndex = UISegmentedControlNoSegment;
            [self sendActionsForControlEvents:UIControlEventValueChanged];
        }
    }
    _previousSelectedSegmentIndex = self.selectedSegmentIndex;
}
38
задан David Callanan 18 August 2017 в 21:35
поделиться

7 ответов

To a first order approximation, the size of an object is the sum of the sizes of its constituent data members. You can be sure it will never be smaller than this.

More precisely, the compiler is entitled to insert padding space between data members to ensure that each data member meets the alignment requirements of the platform. Some platforms are very strict about alignment, while others (x86) are more forgiving, but will perform significantly better with proper alignment. So, even the compiler optimization setting can affect the object size.

Inheritance and virtual functions add an additional complication. As others have said, the member functions of your class themselves do not take up "per object" space, but the existence of virtual functions in that class's interface generally implies the existence of a virtual table, essentially a lookup table of function pointers used to dynamically resolve the proper function implementation to call at runtime. The virtual table (vtbl) is accessed generally via a pointer stored in each object.

Derived class objects also include all data members of their base classes.

Finally, access specifiers (public, private, protected) grant the compiler certain leeway with packing of data members.

The short answer is that sizeof(myObj) or sizeof(MyClass) will always tell you the proper size of an object, but its result is not always easy to predict.

62
ответ дан 27 November 2019 в 03:08
поделиться

Если вам нужна подробная информация о том, как объекты представлены в памяти во время выполнения, вам следует обратиться к спецификации ABI ( Application Binary Interface ). Вам нужно будет посмотреть, какой ABI реализует ваш компилятор; например, GCC версии 3.2 и выше реализуют Itanium C ++ ABI .

8
ответ дан 27 November 2019 в 03:08
поделиться
sizeof(Temp)

покажет вам размер. Скорее всего, это 4 байта (с учетом множества предположений) и это только для int. Функции не занимают места для каждого объекта, они компилируются один раз и связываются компилятором каждый раз, когда они используются.

Невозможно точно сказать, каков макет объекта, однако стандарт этого не делает. t определить двоичное представление для объектов.

Есть несколько вещей, о которых следует помнить о двоичных представлениях, например, они не обязательно являются суммой байтов элементов данных из-за таких вещей, как заполнение структуры

19
ответ дан 27 November 2019 в 03:08
поделиться

Methods belong to the class, not any particular instantiated object.

Unless there are virtual methods, the size of an object is the sum of the size of its non-static members, plus optional padding between the members for alignment. The members will probably be laid out sequentially in memory, but the spec doesn't guarantee ordering between sections with different access specifications, nor ordering relative to the layout of superclasses.

With virtual methods present, there may be additional space taken for vtable and other RTTI information.

On most platforms, executable code goes in the read-only .text (or similarly named) section of the executable or library, and is never copied anywhere. When class Temp has a method public: int function1(int), the Temp metadata may have a pointer to a _ZN4Temp9function1Ei (mangled name may be different depending on compiler) function for the actual implementation, but certainly it would never contain the executable code embedded.

6
ответ дан 27 November 2019 в 03:08
поделиться

Функции-члены не учитывают размер объектов определенного класса. Размер объекта зависит только от переменных-членов. В случае классов, содержащих виртуальные функции, VPTR добавляется в макет объекта. Таким образом, размер объектов - это в основном размер переменных-членов + размер VPTR. Иногда это может быть неверно, поскольку компиляторы пытаются найти переменные-члены на границе DWORD.

4
ответ дан 27 November 2019 в 03:08
поделиться

Это может помочь.

Кроме того, функции классов представлены так же, как и любые другие функции.

0
ответ дан 27 November 2019 в 03:08
поделиться

Если вы хотите изучить макет определенной структуры, макрос offsetof (s, member) также может иметь использовать. Он сообщает вам, как далеко от базового адреса структуры живет конкретный член:

struct foo {
  char *a;
  int b;
};

// Print placement of foo's members
void printFoo() {
  printf("foo->a is %zu bytes into a foo\n", offsetof(struct foo, a));
  printf("foo->b is %zu bytes into a foo\n", offsetof(struct foo, b));
}

int main() {
  printFoo();
  return 0;
}

Будет печатать на типичной 32-битной машине:

foo->a is 0 bytes into a foo
foo->b is 4 bytes into a foo

Тогда как на типичной 64-битной машине он будет печатать

foo->a is 0 bytes into a foo
foo->b is 8 bytes into a foo
2
ответ дан 27 November 2019 в 03:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: