Câu hỏi liên quan

Tại sao các C++ lớp học mà không có member biến chiếm không gian?


0 Phiếu
Đã hỏi 25/5/2016 bởi Trilt_Kone (260 điểm)
I found that both MSVC and GCC compilers allocate at least one byte per each class instance even if the class is a predicate with no member variables (or with just static member variables). The following code illustrates the point.
#include <iostream>
class A
{
public:
   bool operator()(int x) const
   {
      return x>0;
   }
};
class B
{
public:
   static int v;
   static bool check(int x)
   {
      return x>0;
   }
};
int B::v = 0;
void test()
{
   A a;
   B b;
   std::cout << "sizeof(A)=" << sizeof(A) << "\\n"
             << "sizeof(a)=" << sizeof(a) << "\\n"
             << "sizeof(B)=" << sizeof(B) << "\\n"
             << "sizeof(b)=" << sizeof(b) << "\\n";
}
int main()
{
   test();
   return 0;
}
Output:
sizeof(A)=1
sizeof(a)=1
sizeof(B)=1
sizeof(b)=1
My question is why does compiler need it? The only reason that I can come up with is ensure that all member var pointers differ so we can distinguish between two members of type A or B by comparing pointers to them. But the cost of this is quite severe when dealing with small-size containers. Considering possible data alignment, we can get up to 16 bytes per class without vars (?!). Suppose we have a custom container that will typically hold a few int values. Then consider an array of such containers (with about 1000000 members). The overhead will be 16*1000000! A typical case where it can happen is a container class with a comparison predicate stored in a member variable. Also, considering that a class instance should always occupy some space, what type of overhead should be expected when calling A()(value) ?

4 Câu trả lời

0 Phiếu
Đã trả lời 04/6/2016 bởi sutocan (500 điểm)
Nó là cần thiết để đáp ứng một bất biến từ chuẩn C++: mỗi object C++ của cùng một type cần phải có một address duy nhất để được nhận dạng. Nếu các đối tượng đã lên không gian, sau đó các mục trong một mảng nào chia sẻ cùng một địa chỉ.
Đã bình luận 06/6/2016 bởi Gonya (100 điểm)
Chỉ cần để xác nhận nghi ngờ của bạn: * trừ khi nó là một chút-lĩnh vực (9.6), một object nhất có nguồn gốc phải có kích thước không và sẽ chiếm một hoặc nhiều byte dung lượng lưu trữ. Cơ sở class subobjects có thể không size.*
0 Phiếu
Đã trả lời 04/6/2016 bởi Immenthat (160 điểm)
Tất cả các đối tượng hoàn toàn phải có một địa chỉ duy nhất; Vì vậy, họ phải mất ít nhất một byte dung lượng lưu trữ - byte tại địa chỉ của họ.
A điển hình case nơi mà nó có thể xảy ra là một container class với một vị ngữ so sánh được lưu trong một biến member .
trong trường hợp này, bạn có thể sử dụng tối ưu hóa class cơ sở trống : subobject cơ sở được cho phép để có address tương tự như object hoàn tất mà nó là một phần của, do đó, có thể mất không lưu trữ. Vì vậy bạn có thể đính kèm vị ngữ class như là một class cơ sở (có lẽ riêng) chứ không phải là thành viên. Nó là nhiều hơn một chút fiddly để đối phó với hơn so với một thành viên, nhưng nên loại trừ chi phí.
những gì type trên cao nên được dự kiến khi gọi A()(value)?
duy nhất chi phí so với gọi function viên sẽ đi qua các đối số phụ this. Nếu function là inlined, sau đó điều này nên được loại bỏ (như sẽ là trường hợp, nói chung, khi gọi một function member mà không access bất kỳ biến member ).
Đã bình luận 06/6/2016 bởi Luoma (370 điểm)
FYI: subobjects kích thước zero * đang * được cho phép. Vì vậy, nếu bạn lấy được từ một class sản phẩm nào và thêm một member kích thước x, cơ hội là rằng kích thước của type có nguồn gốc cũng x. Điều này được gọi là " class căn cứ sản phẩm nào tối ưu hóa"
0 Phiếu
Đã trả lời 04/6/2016 bởi it_3898 (110 điểm)
Về cơ bản, nó là một hổ tương tác dụng giữa hai yêu cầu:
  • hai đối tượng khác nhau của cùng một type phải ở một địa chỉ khác nhau.
  • trong mảng, không có bất kỳ đệm giữa các đối tượng.
lưu ý rằng các điều kiện đầu tiên một mình không cần không kích thước:
struct empty {};
struct foo { empty a, b; };
đưa ra các yêu cầu đầu tiên có thể dễ dàng được đáp ứng bằng cách có một kích thước zero a theo sau là một byte duy nhất đệm để thực thi một địa chỉ khác nhau, theo sau là một kích thước zero b. Tuy nhiên, được đưa ra
empty array[2];
mà không còn làm việc vì một đệm giữa các đối tượng khác nhau empty[0]empty[1] sẽ không được phép.
0 Phiếu
Đã trả lời 04/6/2016 bởi gb_To (140 điểm)
Về cơ bản, nó là một hổ tương tác dụng giữa hai yêu cầu:
  • hai đối tượng khác nhau của cùng một type phải ở một địa chỉ khác nhau.
  • trong mảng, không có bất kỳ đệm giữa các đối tượng.
lưu ý rằng các điều kiện đầu tiên một mình không cần không kích thước:
struct empty {};
struct foo { empty a, b; };
đưa ra các yêu cầu đầu tiên có thể dễ dàng được đáp ứng bằng cách có một kích thước zero a theo sau là một byte duy nhất đệm để thực thi một địa chỉ khác nhau, theo sau là một kích thước zero b. Tuy nhiên, được đưa ra
empty array[2];
mà không còn làm việc vì một đệm giữa các đối tượng khác nhau empty[0]empty[1] sẽ không được phép.

ToughDev Q&A là gì?

Trang web hỏi đáp cho các bạn đam mê lập trình, phát triển phần mềm và các vấn đề kỹ thuật khác. Với sự giúp đỡ của bạn, chúng tôi hy vọng sẽ xây dựng thành công một thư viện đầy đủ các câu hỏi và trả lời về tất cả các vấn đề có liên quan đến lập trình!







...