Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Put data in class declaration?

In one of Stroustrup's faq question, he gives following example:

template<class Scalar> class complex {
public:
    complex() : re(0), im(0) { }
    complex(Scalar r) : re(r), im(0) { }
    complex(Scalar r, Scalar i) : re(r), im(i) { }
    // ...

    complex& operator+=(const complex& a)
        { re+=a.re; im+=a.im; return *this; }
    // ...
private:
    Scalar re, im;
};

and describes:

This type is designed to be used much as a built-in type and the representation is needed in the declaration to make it possible to create genuinely local objects (i.e. objects that are allocated on the stack and not on a heap) and to ensure proper inlining of simple operations.

Would someone explain this? Put re, im data in class declaration makes class object allocate on stack? And what about inlining? (I can see a operator+= inlined, does he mean this?)

like image 998
user1559625 Avatar asked May 28 '26 02:05

user1559625


2 Answers

The members re and im are allocated inside every complex object. That means that re and im are allocated on the stack if and only if the whole complex object is. If the complex object is a global, then re and im are neither on the stack nor on the heap.

In practice, compilers will put re at offset 0 in the object and im at offset sizeof(Scalar). This means that the code for operator+= doesn't take a lot of assembly instruction to fetch those members. The actual additions themselves probably are just two assembly instruction, so loading the 4 members and storing the two results is a major fraction of the work. And inlining works best if there's little to inline.

like image 149
MSalters Avatar answered May 30 '26 19:05

MSalters


This is a concrete class that is not intended to be derived from (because there is no need).

You probably don't want to define an interface for complex numbers, and derive different kinds of complex numbers (whatever that would be) and use them polymorphically.

By having everything in the class, the compiler can probably easier optimize this than when using an abstract interface and virtual functions.

I don't think there is anything magic here, it is just an example of where using a "value type" class is appropriate.

like image 41
Bo Persson Avatar answered May 30 '26 19:05

Bo Persson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!