How To Implement Method Chaining in C++

C++ Fundamentals

đź–‡Chainđź–‡Yourđź–‡Methodsđź–‡

Photo by Hush Naidoo Jade Photography on Unsplash

Introduction

Method Chaining is one of the many advantages of using OOPs principle to design a software. It is a practice of invoking multiple function in one go rather than calling the them separately. It is also known as Parameter Idiom. If method chaining is implemented properly it makes the code look more elegant and easier to read. This article focuses on C++ but method chaining can be achieved in any OOPs based programming language.

As previously discussed, method chaining is a practice of invoking multiple functions in one go. Let’s dive into the basics of classes and objects before we proceed further. Suppose there is a class List and it has two functions append and print . So to call these function we first need to create an object of the List class. Without the reference of this class we will not be able to access the functions.

The code snippet given below shows what is the traditional way of invoking class methods using an object.

List obj;
obj.append(10);
obj.append(20);
obj.print();

The code snippet given below is our end goal.

List obj;
obj.append(10).append(20).print();

Prerequisites:

The reader should be familiar with the following topics in order to understand the article.

  • Classes and objects
  • Inheritance
  • this keyword in C++(is a pointer to the current object instance)
  • Constructors
  • Templates
  • Type casting

In Case of No Inheritance

Implementing method chaining, in this case, is very straightforward. As already mentioned, to access a member function, we need an object of that class. So if we return *this from the member function, we will achieve method chaining.

In the example given below, there is a single class (class Employee). In every function of class Employee, *this pointer is returned.

https://medium.com/media/ed92f9e35a2a889b21c40d0d87cc5d69/href

When the above code snippet is run the output obtained is:

ABC logged in
ABC taking a break
ABC logged out

If we don’t return *this, the following error will be thrown by the compiler.

Error message by the compiler when method chaining is performed with the function returning *this.
Error message by the compiler when method chaining is performed with the function returning not *this.

Incase of Multilevel Inheritance

Things get tricky when inheritance gets involved. Suppose we have two classes: class Employee and class Developer where Developer derives from Employee.

https://medium.com/media/6f13def7a6362176af3179560cde51de/href

Now, if we were to follow the previous method (return *this), the compiler would throw the following error message.

Error message by the compiler when the functions of the classes returns *this.

The major problem here is the return type. The login function of class Employee returns a reference of type Employee , which does not have any member function named work. To chain the function work , we need the reference of type Developer .

To tackle this problem, templates are brought into the picture. The idea here is to make the base class a generic class and the derived class uses itself as a template argument while inheriting the base class. See the code snippet for a better understanding.

template <class BaseImpl>
class Base {};
class Derived : public Base<Derived> {};

But the work is not completed here. In the methods of the base class, we need to cast the reference using static_cast to the type of the derived class, to chain the methods effortlessly.

NOTE: static_cast can perform conversions between pointers to related classes, not only from the derived class to its base, but also from a base class to its derived.

template <class BaseImpl>
class Base {
public:
BaseImpl &funcBase() {
// do your stuff
return static_cast<BaseImpl&>(*this);
}
};
class Derived : public Base <Derived> {
public:
Derived &funcDerived() {
// do your stuff
return *this;
}
};

In this example given below, there are 3 classes: class Employee , class Developer and class HR .

  • class Employee is the generic base class.
  • class Developer and class HR both will inherit from Employee and pass themselves as template arguments.

https://medium.com/media/e957e1c4bb0dbdabab1d3f7985110c77/href

Output for the above code:

Name 1 logged in
Name 1 writing code
Name 1 taking a break
Name 1 writing code
Name 1 logged out
Name 2 logged in
Name 2 organizing hiring drive
Name 2 organizing company event
Name 2 logged out

Line 51 can also be written as:

Developer dev("Name 1");
dev.login().work().takeBreak().work().logout();

In case of multilevel inheritance with 3 or more classes:

template <class Base1Impl>
class Base1 {
Base1Impl &fun1() {
return static_cast<Base1Impl&>(*this);
}
};
template <class Base2Impl>
class Base2 : public Base1 <Base2Impl> {
Base2Impl &fun2() {
return static_cast<Base2Impl&>(*this);
}
};
class Derived : public Base2 <Derived> {
Base2Impl &fun3() {
return *this;
}
};

Thanks for reading the article. Hope this was helpful. Connect with me on LinkedIn. Cheers 🤜.

Read More


How To Implement Method Chaining in C++ was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding - Medium and was authored by Ashish Yoel

C++ Fundamentals

đź–‡Chainđź–‡Yourđź–‡Methodsđź–‡

Photo by Hush Naidoo Jade Photography on Unsplash

Introduction

Method Chaining is one of the many advantages of using OOPs principle to design a software. It is a practice of invoking multiple function in one go rather than calling the them separately. It is also known as Parameter Idiom. If method chaining is implemented properly it makes the code look more elegant and easier to read. This article focuses on C++ but method chaining can be achieved in any OOPs based programming language.

As previously discussed, method chaining is a practice of invoking multiple functions in one go. Let’s dive into the basics of classes and objects before we proceed further. Suppose there is a class List and it has two functions append and print . So to call these function we first need to create an object of the List class. Without the reference of this class we will not be able to access the functions.

The code snippet given below shows what is the traditional way of invoking class methods using an object.

List obj;
obj.append(10);
obj.append(20);
obj.print();

The code snippet given below is our end goal.

List obj;
obj.append(10).append(20).print();

Prerequisites:

The reader should be familiar with the following topics in order to understand the article.

  • Classes and objects
  • Inheritance
  • this keyword in C++(is a pointer to the current object instance)
  • Constructors
  • Templates
  • Type casting

In Case of No Inheritance

Implementing method chaining, in this case, is very straightforward. As already mentioned, to access a member function, we need an object of that class. So if we return *this from the member function, we will achieve method chaining.

In the example given below, there is a single class (class Employee). In every function of class Employee, *this pointer is returned.

When the above code snippet is run the output obtained is:

ABC logged in
ABC taking a break
ABC logged out

If we don’t return *this, the following error will be thrown by the compiler.

Error message by the compiler when method chaining is performed with the function returning *this.
Error message by the compiler when method chaining is performed with the function returning not *this.

Incase of Multilevel Inheritance

Things get tricky when inheritance gets involved. Suppose we have two classes: class Employee and class Developer where Developer derives from Employee.

Now, if we were to follow the previous method (return *this), the compiler would throw the following error message.

Error message by the compiler when the functions of the classes returns *this.

The major problem here is the return type. The login function of class Employee returns a reference of type Employee , which does not have any member function named work. To chain the function work , we need the reference of type Developer .

To tackle this problem, templates are brought into the picture. The idea here is to make the base class a generic class and the derived class uses itself as a template argument while inheriting the base class. See the code snippet for a better understanding.

template <class BaseImpl>
class Base {};
class Derived : public Base<Derived> {};

But the work is not completed here. In the methods of the base class, we need to cast the reference using static_cast to the type of the derived class, to chain the methods effortlessly.

NOTE: static_cast can perform conversions between pointers to related classes, not only from the derived class to its base, but also from a base class to its derived.
template <class BaseImpl>
class Base {
public:
BaseImpl &funcBase() {
// do your stuff
return static_cast<BaseImpl&>(*this);
}
};
class Derived : public Base <Derived> {
public:
Derived &funcDerived() {
// do your stuff
return *this;
}
};

In this example given below, there are 3 classes: class Employee , class Developer and class HR .

  • class Employee is the generic base class.
  • class Developer and class HR both will inherit from Employee and pass themselves as template arguments.

Output for the above code:

Name 1 logged in
Name 1 writing code
Name 1 taking a break
Name 1 writing code
Name 1 logged out
Name 2 logged in
Name 2 organizing hiring drive
Name 2 organizing company event
Name 2 logged out

Line 51 can also be written as:

Developer dev("Name 1");
dev.login().work().takeBreak().work().logout();

In case of multilevel inheritance with 3 or more classes:

template <class Base1Impl>
class Base1 {
Base1Impl &fun1() {
return static_cast<Base1Impl&>(*this);
}
};
template <class Base2Impl>
class Base2 : public Base1 <Base2Impl> {
Base2Impl &fun2() {
return static_cast<Base2Impl&>(*this);
}
};
class Derived : public Base2 <Derived> {
Base2Impl &fun3() {
return *this;
}
};

Thanks for reading the article. Hope this was helpful. Connect with me on LinkedIn. Cheers 🤜.

Read More


How To Implement Method Chaining in C++ was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding - Medium and was authored by Ashish Yoel


Print Share Comment Cite Upload Translate Updates
APA

Ashish Yoel | Sciencx (2022-06-19T11:54:33+00:00) How To Implement Method Chaining in C++. Retrieved from https://www.scien.cx/2022/06/19/how-to-implement-method-chaining-in-c/

MLA
" » How To Implement Method Chaining in C++." Ashish Yoel | Sciencx - Sunday June 19, 2022, https://www.scien.cx/2022/06/19/how-to-implement-method-chaining-in-c/
HARVARD
Ashish Yoel | Sciencx Sunday June 19, 2022 » How To Implement Method Chaining in C++., viewed ,<https://www.scien.cx/2022/06/19/how-to-implement-method-chaining-in-c/>
VANCOUVER
Ashish Yoel | Sciencx - » How To Implement Method Chaining in C++. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/06/19/how-to-implement-method-chaining-in-c/
CHICAGO
" » How To Implement Method Chaining in C++." Ashish Yoel | Sciencx - Accessed . https://www.scien.cx/2022/06/19/how-to-implement-method-chaining-in-c/
IEEE
" » How To Implement Method Chaining in C++." Ashish Yoel | Sciencx [Online]. Available: https://www.scien.cx/2022/06/19/how-to-implement-method-chaining-in-c/. [Accessed: ]
rf:citation
» How To Implement Method Chaining in C++ | Ashish Yoel | Sciencx | https://www.scien.cx/2022/06/19/how-to-implement-method-chaining-in-c/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.