C++ Class wrapper around fundamental types

你说的曾经没有我的故事 提交于 2019-11-27 22:25:30
Mooing Duck

1) Is there any additional function calling overhead when using someClass.operator+()

No, if the function body is small and in the header, it will be inlined, and have no overhead

2) Is there a way to automatically make the compiler cast the floatWrapper to a float?

struct floatWrapper {
    floatWrapper(float); //implicit conversion from float
    operator float(); //implicit conversion to float.  
};

Again, if the body of the function is small and in the header, it will be inlined, and have no overhead

3) Is there any additional memory overhead?

not if there's no virtual functions. A class is called polymorphic if it declares or inherits any virtual functions. If a class is not polymorphic, the objects do not need to include a pointer to a virtual function table. Moreover, performing dynamic_cast of a pointer/reference to a non-polymorphic class down the inheritance hierarchy to a pointer/reference to a derived class is not allowed, so there is no need for the objects to have some kind of type information.

4) Are there any other problems / performance impacts this could cause?

performance? No.

Also, be sure to implement binary operators that don't modify the lhs as free functions, and overload them to support all relevant permutations of floatWrapper and float.

struct floatWrapper {
    explicit floatWrapper(float);
    operator float(); //implicit conversion to float.  
    floatWrapper operator-=(float);
};
floatWrapper operator-(floatWrapper lhs, floatWrapper rhs) 
{return lhs-=rhs;}
floatWrapper operator-(float lhs, floatWrapper rhs) 
{return floatWrapper(lhs)-=rhs;}
floatWrapper operator-(floatWrapper lhs, float rhs) 
{return lhs-=rhs;}

Here's my attempt at such a thing. Note you'll need a slightly different version for float/double/long double.

It depends on the compiler. If it has loops or allocations, less likely to be inlined.

I think the answers are not completely correct - at least for gcc 4 I have observed a significant overhead due to the constructor and operator calls.

The following takes about twice as long as with long:

typedef intWrapperImpl<long> TestWrapper;
//typedef long TestWrapper;

int main (int argc, char** argv) {
    TestWrapper sum(0);
    TestWrapper test(4);

    for (long i = 0; i < 1000000000L; ++i) {
        sum += test;
    }

    cout << sum << "\n";

    return 0;
}

Using different versions of gcc 4 with and with out optimization led to no differences in the performance.

In this case, adding

intWrapperImpl& operator+=(const intWrapperImpl & v) {value+=v.value; return *this;}

gives only a slight improvement.

Using such a wrapper as if they were base-types in performance critical code seems to be a bad idea. Using them locally and thereby invoking the constructor all the time seems even worse.

This really came as a surprise to me, since it should easily be possible to inline everything and optimize it as if it would be a base-type variable.

Any further hints would be greatly appreciated!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!