Can I use memcpy in C++ to copy classes that have no pointers or virtual functions

前端 未结 11 1181
灰色年华
灰色年华 2020-12-04 13:16

Say I have a class, something like the following;

class MyClass
{
public:
  MyClass();
  int a,b,c;
  double x,y,z;
};

#define  PageSize 1000000

MyClass Ar         


        
11条回答
  •  佛祖请我去吃肉
    2020-12-04 14:04

    [...] but are there any other hidden nasties I should be aware of?

    Yes: your code makes certain assumptions that are neither suggested nor documented (unless you specifically document them). This is a nightmare for maintenance.

    Also, your implementation is basically hacking (if it's necessary it's not a bad thing) and it may depend (not sure on this) on how your current compiler implements things.

    This means that if you upgrade compiler / toolchain one year (or five) from now (or just change optimization settings in your current compiler) nobody will remember this hack (unless you make a big effort to keep it visible) and you may end up with undefined behavior on your hands, and developers cursing "whoever did this" a few years down the road.

    It's not that the decision is unsound, it's that it is (or will be) unexpected to maintainers.

    To minimize this (unexpectedness?) I would move the class into a structure within a namespace based on the current name of the class, with no internal functions in the structure at all. Then you are making it clear you're looking at a memory block and treating it as a memory block.

    Instead of:

    class MyClass
    {
    public:
        MyClass();
        int a,b,c;
        double x,y,z;
    };
    
    #define  PageSize 1000000
    
    MyClass Array1[PageSize],Array2[PageSize];
    
    memcpy(Array1,Array2,PageSize*sizeof(MyClass));
    

    You should have:

    namespace MyClass // obviously not a class, 
                      // name should be changed to something meaningfull
    {
        struct Data
        {
            int a,b,c;
            double x,y,z;
        };
    
        static const size_t PageSize = 1000000; // use static const instead of #define
    
    
        void Copy(Data* a1, Data* a2, const size_t count)
        {
            memcpy( a1, a2, count * sizeof(Data) );
        }
    
        // any other operations that you'd have declared within 
        // MyClass should be put here
    }
    
    MyClass::Data Array1[MyClass::PageSize],Array2[MyClass::PageSize];
    MyClass::Copy( Array1, Array2, MyClass::PageSize );
    

    This way you:

    • make it clear that MyClass::Data is a POD structure, not a class (binary they will be the same or very close - the same if I remember correctly) but this way it is also visible to programmers reading the code.

    • centralize the usage of memcpy (if you have to change to a std::copy or something else) in two years you do it in a single point.

    • keep the usage of memcpy near the implementation of the POD structure.

提交回复
热议问题