C + + Learning XIV. Advanced return object of class

Posted by uknowho008 on Sun, 20 Feb 2022 20:25:26 +0100

preface

This article first summarizes the use of dynamic memory in classes, and then records the returned objects.

Class and dynamic memory summary

  • If new is used in the constructor to allocate dynamic memory, delete must be used in the destructor to free dynamic memory.
  • There is only one destructor. Therefore, when there are multiple constructors, the compatibility between new and new [] should be considered.
  • If the constructor allocates dynamic memory, you need to define a deep copy constructor and overload a deep copy assignment operator.

Function return object

In addition to returning ordinary objects, functions can also return references (or pointers) of objects, const objects, const reference objects or pointers.

Returns a non const object

As mentioned in the previous article, the function return object will call the copy constructor (the compiler turns off RVO), which increases the program running time and memory usage.

  • When the object to be returned is a local variable, a normal object is returned.

Return const object

The purpose of returning const type is that const constant will not be modified.

  • When the object to be returned is a local variable and you do not want the function call statement to be assigned, the const object is returned.

Returns a non const reference object

The advantage of returning a reference (pointer) to an object is that the copy constructor is not called.

  • When the object to be returned is the reference passed in by the function and the returned object can be modified later, the reference of non const object is returned

Note: the returned reference must be an object that still exists after the end of the function. Local objects created in functions cannot be returned through references and pointers.

Return const reference object

Returning const reference can prevent the function call statement from being assigned. On the other hand, if you want to return the incoming const reference, the return type must be const reference.

Examples

#include <cstdio>
#include <iostream>
#include <cstring>

using std::ostream;

class A{
    private:
        int a_;
        int b_;
        int c_;
    public:
        A();
        A(int, int, int);

        A operator- (const A&) const;
        const A operator+ (const A&) const;

        const A& operator= (const A&);
        friend ostream& operator<< (ostream& os,
                                    const A&);
};

A::A(): a_(0), b_(0), c_(0) {}

A::A(int a, int b, int c): a_(a), b_(b), c_(c) {}

A A::operator- (const A& s) const{
    int a = a_ - s.a_;
    int b = b_ - s.b_;
    int c = c_ - s.c_;
    return A(a, b, c);
}

const A A::operator+ (const A& s) const{
    int a = a_ + s.a_;
    int b = b_ + s.b_;
    int c = c_ + s.c_;
    return A(a, b, c);
}

ostream& operator<< (ostream& os, const A& s){
    os << s.a_ << " " << 
        s.b_ << " " << 
        s.c_ << '\n';
        return os;
}

const A& A::operator= (const A& s){
    return s;
}

const A func(const A& s){
    return s;
}

const A& funcc(const A& s){
    return s;
}

int main(){
	A s1(1, 1, 1);
	A s2(2, 2, 2);
	// insert code
	
	return 1;
}

In the above code, if you insert the following code after / / insert code:

s1 - s2 = s1; // ok 
s1 + s2 = s2; // error!

s1 + s2 = s2; Error: passing 'const a' as' this' argument discards qualifiers [- fpermissive];, The reason is that returning const object can prevent it from being assigned after calling.

s1 = s1 = s1; // ok
(s1 = s1) = s1; // error!

=It is right associativity, so s1 = s1 = s1 is actually s1 = (s1 = s1) no problem, and (s1 = s1) = s1 returns const reference, which will naturally report error: passing 'const a' as' this' argument discards qualifiers [- fpermissive]

A func(const A& s){ // ok
    return s;
}

A& funcc(const A& s){ // error!
    return s;
}

const A& funccc(A& s){ // ok
	return s;
}

If the return types of func and funcc are changed to non const, func is OK, but funcc reports error: binding reference of type 'A &' to 'const a' discards qualifiers,

func returns an object (variable). The copy constructor creates a temporary object with the same return type according to s, so it doesn't matter whether the return is const or not.

funcc returns a reference, so no temporary variable will be created, return s; Returns s, which is a const reference. If the return type is non const, the const state of S is not safe, which violates the logic of C + +.

return s in funccc; S in is a non const reference and the return type is const. At this time, the returned s changes from non const to const. The state is safe and does not violate C + + logic.

In a word, the core reason for the frequent error discards qualifiers of const keyword is to maintain the security of variable state. If the compiler thinks the return method is unsafe, it will report discards qualifiers.

Postscript

The next chapter goes to the chapter of class inheritance.

Topics: C++