[C/C++ learning programming] C++ uses new and does not use new to create class objects difference

Foreword: When I first learned C++, I was not used to using new. Later, when I looked at the programs of foreigners, I found that almost all use new. Thinking about it, the difference is not too big, but in larger project design, sometimes new is not used. It does bring many problems.

Of course this is all related to the usage of new. New creates a class object and needs to use delete to delete it after use, similar to requesting memory. Therefore, new is sometimes not suitable. For example, in frequent calls, it is not a good choice to use a local new class object. Using a global class object or an initialized global class pointer seems more efficient.

 

One, the difference between new creation of class objects and not new

The following is a summary of some of the characteristics of new creation class objects:

New to create a class object requires pointer reception, one initialization, multiple use

New created class object needs to be destroyed after use

New creates objects directly using heap space, and locally does not use new to define class objects to use stack space

The new object pointer is widely used, such as function return value, function parameter, etc.

Frequent calling occasions are not suitable for new, just like new application and release of memory

Two, new creates a class object instance

1. Examples of new creation class objects:

CTest* pTest = new CTest();

delete pTest;

pTest is used to receive pointers to class objects.

Do not use new, directly use the class definition statement:

 

Ctesibus mtes;

This kind of creation method does not need to be manually released after use, and this type of destructor will be executed automatically. The new application object will only execute the destructor when delete is called. If the program exits without executing delete, it will cause a memory leak.

2. Only define class pointers

This is very different from not declaring the object with new. The class pointer can be defined first, but the class pointer is just a general pointer. Any memory space is allocated for this class of object before new. such as:

CTest * pTest = NULL;

However, a class object created in a common way has allocated memory space at the beginning of its creation. And the class pointer, if the object has not been initialized, there is no need to delete it.

3. New object pointer as function parameter and return value

The following is an example of Tianyuan's handwriting, not very rigorous. Mainly indicate the use of class pointer objects as return values ​​and parameters.

 

                                                          

Example:

A brief summary of the memory allocation of the class, the code snippet is as follows:

#include <iostream>

usingnamespacestd;

classClassA {

    private:

        intA;

        intB;



    voidprin1() {

    }



    voidprin2() {

    }



    virtualvoidprin3() {

    }

};



classClassB : publicClassA {

    public:

        intC;

        intD;



    voidprin4() {

    }



    voidprin5() {

    }



    virtualvoidprin6() {

    }

};



intmain(intargc, char* argv[]) {

    cout<<sizeof(ClassA)<<endl;     // 16

    cout<<sizeof(ClassB)<<endl;     // 24



    return0;

}

test environment:

Ubuntu 12.04.5 LTS   x86_64 GNU/Linux

g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 Compilation parameters -m64 

The result is

homer@homer-pc:~/Desktop$ g++ testMem.c -o testMem && ./testMem

16

24

Why is it so?

32-bit system int occupies 4 bytes, 64-bit system int also occupies 4 bytes (not 8 bytes), and all virtual functions in a class are managed by a virtual function pointer, the size of the class object only includes this The vptr pointer (the pointer sizeof is 8 bytes on a 64-bit machine), and other virtual functions are managed in another memory space. The vptr pointer is 8 bytes in size on a 64-bit machine (4 on a 32-bit machine) Bytes). Note that ordinary member functions do not occupy the size of the class object, because ordinary member functions are managed by the this pointer. The this pointer of an object is not part of the object itself, and will not affect the result of sizeof (object).

sizeof(ClassA)

1) int A and int B each occupies 4 bytes, considering the rules of the 64-bit machine compiler, combined into 8 bytes

2) virtual void prin3() The vptr pointer of the virtual function, which occupies 8 bytes on the 64-bit machine compiler

3) The total sizeof(ClassA) is 8 + 8 = 16 bytes

The scope of this is inside the class. When accessing a non-static member of the class in a non-static member function of the class, the compiler will automatically pass the address of the object itself as an implicit parameter to the function. This this pointer will be placed in different locations depending on the compiler, it may be a stack, it may be a register, or even a global variable.

In fact, no matter how the subclass inherits, using sizeof() to calculate the size of the class will include the space occupied by the private member variables in the parent class. In other words, the private variables are also allocated memory in the subclass, but you It cannot be accessed directly. This plays a protective role. It is like a jewelry. Shared inheritance is an open exhibition, while private inheritance is to lock the jewelry, but you can’t move it. If you want to move the jewelry, if there is a housekeeper (the public of the base class) Defines some member functions that operate on its private variables,) can only let the butler do it for you.

sizeof(ClassB)

1) int A and int B each occupies 4 bytes, which are private variables in the parent class ClassA, combined occupy 8 bytes

2) virtual void prin3() virtual function vptr pointer, the parent class ClassA will not allocate space in the subclass

 

3) int C and int D each occupy 4 bytes, space will be allocated in the subclass, and the combined will occupy 8 bytes

4) virtual void prin6() The vptr pointer of the virtual function, which occupies 8 bytes on the 64-bit machine compiler

5) The total sizeof(ClassB) is 8 + 8 + 8 = 24 bytes

Note : The above example is tested on a 32-bit compiler, sizeof(ClassA) and sizeof(ClassB) are 12 and 20 bytes respectively (the virtual function pointer takes up 4 bytes less space)

 

Knowledge extension:

1) 空 ClassA(验证空Class占用空间大小)

classClassA {

    private:



    voidprin1() {

    }



    voidprin2() {

    }

};



cout<<sizeof(ClassA)<<endl;     // 1



2) ClassA 只有一个char(验证编译器对其规则)

classClassA {

    private:

        charC;



    voidprin1() {

    }



    voidprin2() {

    }

};



cout<<sizeof(ClassA)<<endl;     // 1



3)ClassA 有一个char和一个虚函数(或一个long型)(验证编译器对其规则二)

classClassA {

    private:

        charC;



    voidprin1() {

    }



    voidprin2() {

    }



    virtualvoidprin3() {

    }

};



cout<<sizeof(ClassA)<<endl;     // 16



4)ClassA 有一个char和一个虚函数(或一个long型),且对调char和虚函数的先后顺序(验证编译器对其规则三)

classClassA {



    voidprin1() {

    }



    voidprin2() {

    }



    virtualvoidprin3() {

    }



    private:

        charC;

};



cout<<sizeof(ClassA)<<endl;     // 16



5)ClassA 有一个char,一个int,一个虚函数(或一个long型)(验证编译器对其规则四)

classClassA {

    private:

        charC;

        intA;



    voidprin1() {

    }



    voidprin2() {

    }



    virtualvoidprin3() {

    }

};



cout<<sizeof(ClassA)<<endl;     // 16



6)ClassA 有一个char,一个int(验证编译器对其规则五)

classClassA {

    private:

        charC;

        intA;



    voidprin1() {

    }



    voidprin2() {

    }

};



cout<<sizeof(ClassA)<<endl;     // 8



7)ClassA 只有一个int(验证编译器对其规则六)

classClassA {

    private:

        intA;



    voidprin1() {

    }



    voidprin2() {

    }

};



cout<<sizeof(ClassA)<<endl;     // 4

 

 

Summarized as follows:

1) The sizeof of the empty class is 1 byte

2) Only one char class, sizeof is one byte

 

3) The class contains char and virtual function, and the largest variable or pointer will be used as the compiler alignment rule. For example: the virtual function pointer occupies 8 bytes (64-bit compiler), although char only occupies 1 byte, However, 7 bytes are left after alignment, and the merged class occupies 8 (pointer) + 1 (char) + 7 (aligned null byte) = 16 bytes

4) Alignment rules have nothing to do with the order of variables or virtual functions, only the maximum variable type or function pointer. The function pointer is related to the maximum number of alignment bits of the compiler (not easy to understand, please continue to read)

5) Char and int occupies 8 bytes, the virtual function pointer occupies 8 bytes, and the 8 bytes of the largest virtual function pointer is used for alignment, of which char occupies a spare 3 bytes combined to occupy 4, int Occupies 4 bytes, aligned according to the 8-bit rule, totaling 16 bytes

6) A char and int combined occupies 8 bytes, no virtual function, at this time the largest variable type int is aligned, so char occupies 1 byte, 3 bytes, 4 bytes

7) An int occupies 4 bits, which is the largest alignment rule by itself; 2) A char also occupies 1 byte, which has nothing to do with the compiler's maximum 64-bit alignment rule (that is, an int or a char, no Expand to occupy 8 bytes)

 

Here, another very interesting question is extended. Why is the empty class sizeof not 0 but 1?

To answer this question, you need to return to the problem of compiler and class instantiation. After reading "Deep Exploration of the C++ Object Model", the classes are divided into abstract classes and ordinary classes. Empty classes are ordinary classes and can be instantiated.

Each instance of a class has a unique address in memory. In order to achieve this goal, the compiler will often implicitly add a byte to an empty class, so that the empty class is unique in memory after instantiation Address, so the empty class ClassA in 1) will occupy 1 byte by default.

For more dry goods sharing, please pay attention to my penguin circle if you have relevant learning materials! ! !

Guess you like

Origin blog.csdn.net/weixin_45713725/article/details/109310215