Learn C++ https://learncplusplus.org C++ Syntax, Resources, Tutorials, And Code Snippets Mon, 24 Jun 2024 10:42:52 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.5 https://i0.wp.com/learncplusplus.org/wp-content/uploads/2025/01/cropped-cbuilder-logo-128.png?fit=32%2C32&ssl=1 Learn C++ https://learncplusplus.org 32 32 184929441 Learn Copy Constructors in C++ Classes https://learncplusplus.org/learn-copy-constructors-in-c-classes/ Fri, 28 Jun 2024 05:00:00 +0000 http://learncplusplus.org/?p=4538 In C++, constructors are one of the important parts of class types. There are different constructor types in C++ classes and the Copy Constructor is one of these. Copy Constructors are not only used in...

The post Learn Copy Constructors in C++ Classes first appeared on Learn C++.]]>
In C++, constructors are one of the important parts of class types. There are different constructor types in C++ classes and the Copy Constructor is one of these. Copy Constructors are not only used in classes but also used with struct and union data types. In this post, we will try to explain the types of Copy Constructors in modern C++.

What is the Constructor in C++ classes?

The Constructor in C++ is a function, a method in the class, but it is a ‘special method’ that is automatically called when an object of a class is created. We don’t need to call this function. Whenever a new object of a class is created, the Constructor allows the class to initialize member variables or allocate storage. This is why the name Constructor is given to this special method. Here is a simple constructor class example below.

class myclass
{         
  public:   
    myclass()
    {
       std::cout << "myclass is constructed!\n";
    };
};

What is Copy Constructor in C++?

The Copy Constructor in classes (i.e class_name) is a non-template constructor whose first parameter is class_name&‍const class_name&‍volatile class_name&‍, or const volatile class_name&‍ . It can be used with no other parameters or with the rest of the parameters all have default values.

The Copy Constructor is a constructor type for classes that class_name must name the current class, or it should be a qualified class name when it is declared at namespace scope or in a friend declaration.

What are the types of Copy Constructors in C++ ?

Now let’s see different types of copy constructors in usage. First, let’s learn deceleration of a copy constructor.

1. Typical Declaration of a Copy Constructor

Syntax to declare Copy Constructor,

class_name (const class_name &)

Syntax to use Copy Constructor, this copy source_class to new_class as below,

class_name new_class(source_class);

An example with a class;

#include <iostream>
 
class myclass
{
  public:
 int param;
 myclass()   // Default Constructor
 {
 };
 
 myclass(const myclass& a) // Copy Constructor
 {
 param = a.param; // we need to copy values of each properties as in here
 };
};
 
 
int main()
{
 myclass class1;
 class1.param=100;
 std::cout << class1.param << '\n' ;
 
 // Copy Class1 to Class2 by using Copy Constructor
 myclass class2(class1);
 std::cout << class2.param << '\n' ;
 
 getchar();
 return 0;
}

and the output will be,

100
4358220

Here are more details and a full example about this feature.

2. Forced Copy Constructor (Default Copy Constructor)

In C++, we can force a copy constructor of a class to be generated by the compiler.

Syntax,

class_name ( const class_name & ) = default;

An example with a class,

class myclass
{
  public:
	int param;
	myclass()   // Default Constructor
	{
	};

	myclass(const myclass& ) = default; // Copy Constructor with atrributes as default
};


int main()
{
	myclass class1;
	class1.param=100;
	myclass class2(class1);

	std::cout << class1.param << '\n' ;
	std::cout << class2.param << '\n' ;
	getchar();
	return 0;
}

Now, this is same as example before and copy constructor copies not only class properties and methods but also copies values of current class without and definition by user. This method is very useful to copy all parameters in one time. Result will be as follows,

100
100

Here are more details and a full example about this feature,

3. Avoiding Implicit Generation of the Copy Constructor (Deleted Copy Constructor)

Deleted Copy Constructor is used if you are Avoiding implicit generation of the copy constructor.

Syntax,

class_name ( const class_name & ) = delete;

In example, copy constructor can be defined with attributes as delete;

class myclass
{
  public:
 myclass()   // Default Constructor
 {
 };
 
 myclass(const myclass& ) = delete; // Copy Constructor with attributes as delete
};

Here are more details and a full example about this feature,

4. Implicitly-Declared Copy Constructor

In C++, the compiler declares a Copy Constructor as a non-explicit inline public member of its class If a copy constructor is not defined for a class type (struct, class, or union), We can Implicitly declare a copy constructor when defining a new class. Remember that copy constructor has this syntax,

class_name (const class_name& ) // Copy Constructor
{
 
};

and this Copy Constructor will be declared implicitly when declaring a new class as below,

class new_class_name : access_type class_name
{
   // Copy Constructor will be Declared Implicitly
};

Here is an example,

class  myclass
{
  public:
 myclass()   // Default Constructor
 {
 };
 
 myclass(const myclass& ) // Copy Constructor
 {
 
 };
};
 
class my_otherclass : public myclass  // Implicitly-Declared Copy Constructor
{
};

Here are more details and a full example about this feature,

5. Implicitly-Defined Copy Constructor

The implicitly-defined copy constructor is defined by the compiler if Implicitly Declared Copy Constructor is not deleted. In union types this implicitly-defined copy constructor copies the object representation by using std::memmove statement. In other non-union class types (like classes and structs), their constructor performs full member-wise copy of the object’s bases and non-static members, in their initialization order, using direct initialization. Remember that copy constructor has this syntax,

class_name (const class_name& ) // Copy Constructor
{
 
};

and this Copy Constructor will be defined implicitly when declaring a new class as below,

class new_class_name : access_type class_name
{
   new_class_name() : clas_name() { } // Copy Constructor Defined Implicitly
};

The generation of the implicitly-defined copy constructor is deprecated if T has a user-defined destructor or user-defined copy assignment operator.

Here are more details and full example about this feature.

6. Deleted Implicitly-Declared Copy Constructor

In C++, we can implicitly declare a copy constructor while it is deleted in previous class. The implicitly-declared or defaulted copy constructor for a class is defined as deleted if,

  • class has non-static data members that cannot be copied
  • class has direct or virtual base class that cannot be copied
  • class has direct or virtual base class with a deleted or inaccessible destructor
  • class is a union-like class and has a variant member with non-trivial copy constructor
  • class has a data member of rvalue reference type;
  • class has a user-defined copy constructor or copy assignment operator

The compiler declares a Copy Constructor as a non-explicit inline public member of its class If a copy constructor is not defined for a class type (struct, class, or union), We can Implicitly declare a copy constructor when defining a new class.

Remember that copy constructor has this syntax,

class_name (const class_name& ) // Copy Constructor
{
 
};

and this Copy Constructor will be declared implicitly when declaring a new class as below,

class new_class_name : access_type class_name
{
   // Copy Constructor will be Declared Implicitly
};

If we combine both with a Deleted copy Constructor, here is an Deleted Implicitly-Declared Copy Constructor example

class  myclass
{
  public:
 myclass()   // Default Constructor
 {
 };
 
 myclass(const myclass& ) = delete; // Copy Constructor Deleted
};
 
class my_otherclass : public myclass 
{
 my_otherclass(const myclass& a) : myclass() // Deleted Implicitly-Declared Copy Constructor
 {
 };
};

Here are more details and a full example about this feature,

7. Trivial Copy Constructor

A Trivial Copy Constructor for a non-union class effectively copies all properties (scalar sub objects, all sub objects of sub objects) of the argument and performs no other action. However, padding bytes need not be copied, and even the object representations of the copied sub objects need not be the same as long as their values are identical. In general, the syntax to declare Copy Constructor is the following:

class_name (const class_name &)

If you don’t declare anything as above, the class has a Copy Constructor, and a new subclass may have this Copy Constructor which is called a Trivial Copy Constructor. Syntax to use Copy Constructor which copies source_class to new_class as below,

class_name new_class(source_class);

The copy constructor for a class is trivial if all below is maintained,

  • The class is not user-provided
  • The class has no virtual member functions
  • The class has no virtual base classes

and also note that,

  • The copy constructor selected for every direct base of the class is trivial
  • The copy constructor selected for every non-static class type (or array of class type) member of the class is trivial

Here are more details and a full example about this feature,

8. Eligible Copy Constructor

Since C++11, a copy constructor is defined as eligible if it is not deleted.

Since C++20, a copy constructor is eligible if

  • Copy Constructor is not deleted, and
  • Copy Constructor associated constraints, if any, are satisfied,
  • no copy constructor with the same first parameter type is more constrained than it

The triviality of eligible copy constructors determines whether the class is an implicit-lifetime type and whether the class is a trivially copyable type.

class myclass
{
  public:
 myclass(const myclass&) // Eligible Copy Constructor
 {
 };
 
};

Here are more details and a full example about this feature,

What Is Assignment Operator Overloading? C++ Builder logo

C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.

There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise version.

The post Learn Copy Constructors in C++ Classes first appeared on Learn C++.]]>
4538
Learn How To Use Types Of Destructors In C++? https://learncplusplus.org/learn-how-to-use-types-of-destructors-in-c/ Wed, 26 Jun 2024 05:00:00 +0000 http://learncplusplus.org/?p=4570 When we are developing modern applications, we construct many objects by using our classes, they normally deconstruct themself when they are out of scope, sometimes we need operations to deconstruct them which means we need...

The post Learn How To Use Types Of Destructors In C++? first appeared on Learn C++.]]>
When we are developing modern applications, we construct many objects by using our classes, they normally deconstruct themself when they are out of scope, sometimes we need operations to deconstruct them which means we need to define destructors. Destructors are not only used in classes but also used with struct and union data types. In this post, we will try to explain how to use a Typical Destructor in Classes with given examples.

What is a constructor in C++?

The Constructor in C++ is a function, a method in the class, but it is a ‘special method’ that is automatically called when an object of a class is created. We don’t need to call this function. Whenever a new object of a class is created, the Constructor allows the class to initialize member variables or allocate storage. This is why the name Constructor is given to this special method. Here is a simple constructor class example below.

class myclass
{         
  public:   
    myclass()
    {
       std::cout << "myclass is constructed!\n";
    };
};

What is a destructor in C++?

The Destructor in classes (i.e class_name) is a special member function to delete objects, in other terms it is called when the lifetime of an object ends. The purpose of the destructor is to do operations when destruct the object. The object may have acquired or allocated data on memory on runtime, they need to be freed too when objects are being deleted, destructor is the function that frees the resources of the object. When we construct an object, sometimes we need operations to deconstruct. Destructors are not only used in classes but also used with struct and union data types.

class myclass
{
   public:
   ~myclass() // Destructor
    {
    }; 

};

What are the types of destructors in modern C++?

1. Typical Declaration of a Destructor

The Destructor in classes (i.e class_name) is a special member function to delete objects, in other terms it is called when the lifetime of an objects ends. The purpose of the destructor is to do operations when destruct the object. Object may have acquired or allocated data on memory on runtime, they need to be freed too when objects are being deleted, destructor is the function that free the resources of object.

To define a destructor in a class we use ‘~‘ symbol with the same class name and parenthesis as given below,

Syntax,

~ class_name ();

Destructor declaration example in a class.

class myclass
{
   public:
   ~myclass() // Destructor
    {
    }; 

};

If you want to learn more details about this type with a full C++ example, please follow this post.

2. Virtual Destructor

in C++The Destructor in classes (i.e. class_name) is a special member function to delete objects, in other terms it is called when the lifetime of an objects ends. The purpose of the destructor is to do operations when destruct the object. Object may have acquired or allocated data on memory on runtime, they need to be freed too when objects are being deleted, destructor is the function that free the resources of object.

Virtual Destructor is usually required in a base class, and it is used by the class which has this base class. Note that, deleting a class object through pointer to base invokes undefined behavior unless the destructor in the base class is virtual:

Syntax,

virtual ~class_name ();

Virtual destructor declaration example in a class,

class myclass
{
   public:
   virtual ~myclass() // Virtual Destructor
   {
   }; 

};

If you want to learn more details about this type with a full C++ example, please follow this post,

3. Pure Virtual Destructor

A Virtual Destructor is usually required in a base class, and it is used by the class which has this base class and described in previous section.

A Pure Virtual Destructor is defined in a base class with =0; statement, and its body is declared outside of the class. Pure Virtual Destructors are mostly used in C++ standard and it is generally used in libraries (dynamic DLL or static)although there are use cases for virtual destructors. Note that, if your class contains a pure virtual destructor, it should provide a function body for the pure virtual destructor. If you are asking why a pure virtual function requires a function body the answer is destructors are not actually overridden, rather they are always called in the reverse order of the class derivation. That means, firstly a derived class destructor will be invoked, and then the base class destructor will be called. If the definition of the pure virtual destructor is not provided, then the compiler and linker enforce the existence of a function body for pure virtual destructors.

Syntax,

virtual ~class_name () = 0;

Virtual destructor declaration example in a class.

class myclass
{
   public:
   virtual ~myclass() = 0; // Pure Virtual Destructor

};

If you want to learn more details about this type with a full C++ example, please follow this post.

4. Forcing a Destructor (Forced Destructor, Defaulted Destructor)

Defaulted destructors can be declared with = default; term at the end that means it is forcing a destructor to be generated by the compiler.

Syntax,

~class_name () = default;
<decl-specifier> ~ class_name () = default;

 Forcing a destructor to be generated by the compiler.

class myclass
{
   public:
      ~myclass() = default; // Defaulted Destructor, Forcing Destructor
};

If you want to learn more details about this type with a full C++ example, please follow this post.

5. Deleted Destructor, (Disabling The Implicit Destructor, Deleted Implicit Destructor)

Since C++11 a class type can be defined as deleted by using = delete. This can be a implicitly-declared or explicitly-defaulted destructor. Here is how we can use it.

~class_name () = delete;

Syntax,

<decl-specifier> ~class_name () = delete;
class my_class
{
  public:
   ~my_class() = delete;  // Destructor that is deleted

};

In other words, the destructor can be disabled by the = delete; statement for the Implicit Destructor Declaration. Disabling the Implicit Destructor a destructor to be generated by the compiler.

class myclass
{
   public:
      ~myclass() = delete; // Disabling The Implicit Destructor
};

If you want to learn more details about this type with a full C++ example, please follow this post.

6. Implicitly-Defined Destructor

An implicitly defined destructor is a destructor method with a body generated and compiled and it is not deleted. If a destructor declared and it is not deleted, it can be implicitly defined by the compiler when it is used by other classes. This implicitly defined destructor may have an empty body. If this satisfies the requirements of a constexpr_destructor, the generated destructor is constexpr

In this example below, the implicitly defined destructor is called in the main function from the class1 to destroy the class1, as you see it is declared in my_class and can be implicitly used from the my_otherclass

Here is an example of an Implicitly-Defined Destructor

class my_class
{
  public:
   ~my_class() // Destructor
   {
 std::cout << "Class has been destructed\n";
   };
};
 
class my_otherclass
{
  public:
 my_class test; // This class has Implicitly-Defined Destructor
};

If you want to learn more details about this destructor type with a full C++ example, please follow this post.

7. Implicitly-Declared Destructor

An implicitly-declared destructor is a destructor method in a class and If there is no declared destructor that is provided in a class (struct, class, or union), the compiler declares a destructor itself as an inline public member of its class,

As with any implicitly declared special member function, the exception specification of the implicitly declared destructor is non-throwing unless the destructor of any potentially constructed base or member is potentially throwing implicit definition would directly invoke a function with a different exception specification, until C++17. In practice, implicit destructors are noexcept unless the class is “poisoned” by a base or member whose destructor is noexcept(false).

class my_class
{
  public:
   ~my_class() // Destructor
   {
		std::cout << "Class has been destructed\n";
   };
};

class my_otherclass  : my_class
{
  public:
	// This class has Implicitly-Declared Destructor
};

If you want to learn more details about this destructor type with a full C++ example, please follow this post.

8. Deleted Implicitly-Declared Destructor

The implicitly-declared or defaulted destructor for the class is a destructor method that it is defined as deleted since C++11. To say that is a Implicitly Declared Destructor, any of the following below should be maintained,

  • The class has a non-static data member that cannot be destructed
  • The class has direct or virtual base class that cannot be destructed
  • The class is a union and has a variant member with non-trivial destructor

also note that,

  • If the base class has a virtual destructor then implicitly-declared destructor is virtual
  • A defaulted prospective destructor for the class is defined as deleted if it is not the destructor for that class

According to open-std.org resource, any direct or virtual base class or non-static data member has a type with a destructor that is deleted or inaccessible from the defaulted default constructor or default constructor.

Here is an Implicitly-Declared Default Constructor example that gives an Error.

class my_class
{
  public:
   ~my_class() = delete;  // Destructor that is deleted

};

class my_otherclass  : public my_class
{
  public:
	// This class has Deleted Implicitly-Declared Destructor
};

If you want to learn more details about this destructor type with a full C++ example, please follow this post,

9. Trivial Destructor

In C++, normally all base classes have trivial destructors and all non-static data members of class type have trivial destructors. A destructor of a class is trivial if,

  • It is not implicitly declared, or explicitly defined as defaulted on its first declaration, means it is not user provided.
  • It is not virtual and the base class destructor is not virtual.

For example,

class my_class
{
  public:
   // This class has a trivial destructor as a default
};

10. Prospective Destructor

Since C++20, prospective destructors are special member functions of that class. We may have one or more prospective destructors and we can select one of them as a destructor. At the end of the definition of the class, we can determine which prospective destructor is the destructor, to do this overload resolution is performed between these defined prospective destructors.

How To Convert Char Array String To Unicode String Correctly In C++?

C++ Builder is the easiest and fastest C and C++ compiler and IDE for building simple or professional applications on the Windows operating system. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for UIs.

There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise versions of C++ Builder and there is a trial version you can download from here.

The post Learn How To Use Types Of Destructors In C++? first appeared on Learn C++.]]>
4570
How To Convert u32string To A wstring In C++ https://learncplusplus.org/how-to-convert-u32string-to-a-wstring-in-c/ Mon, 24 Jun 2024 05:00:00 +0000 https://learncplusplus.org/?p=9123 While C++ is one of the most modern programming languages in the world, in 2024, it still has problems with strings and conversions. One of the problems is new std::basic_string types, it is hard to...

The post How To Convert u32string To A wstring In C++ first appeared on Learn C++.]]>
While C++ is one of the most modern programming languages in the world, in 2024, it still has problems with strings and conversions. One of the problems is new std::basic_string types, it is hard to display and convert them. For example, there are no perfect conversion methods between basic_strings, especially, from higher character type strings to lower character type strings, such as conversion from std::u32string to a std::wstring. In this post, we will explain these string types and how you can convert from a u32string to a wstring.

What is a wstring (std::wstring) in C++ ?

Wide strings are the string class for ‘wide’ characters represented by wstring. Alphanumeric characters are stored and displayed in string form. In other words wstring stores alphanumeric text with 2 or 4 byte chars. Wide strings are the instantiation of the basic_string class template that uses wchar_t as the character type. The type definition of a wstring is as given below:

typedef std::basic_string<wchar_t> std::wstring;

What is u32string (std::u32string)?

The u32string (std::u32string or std::pmr::u32string) is the string class data type for the 32-bit characters defined in the std and std::pmr namespaces. It is a string class for 32-bit characters.

This instantiates the basic_string class template that uses char16_t as the character type, with its default char_traits and allocator types. For example, the std::string uses one byte (8 bits) while the std::u32string uses four bytes (32 bits) per each character of the text string. In basic string definition, std::u32string is defined as std::basic_string<char32_t>. Type definition can be shown as below,

typedef basic_string<char32_t> u32string;

Note that we released about conversion from u16string to wstring as discussed below.

Now, let’s see how we can convert u32string to a wstring.

Is there a simple example of how to use u32string and wstring in C++?

Here is a simple example of how to use std::u32string and std::wstring in C++.

#include <iostream>

int main()
{
	std::wstring   str2 = L"This is a wstring";
	std::u32string str4 = U"This is a u32string";

	std::pmr::wstring   pstr2 = L"This is a wstring";
	std::pmr::u32string pstr4 = U"This is a u32string";

	return 0;
}

How can we convert u32string to a wstring in C++?

First of all, we should say that we do not recommend converting the higher-byte string to a lower-byte string. Let’s assume that a developer wants to extract ASCII characters from u32string, and they don’t care about other character losses. In this situation, maybe this developer needs to convert u32string to wstring or later to a string or to a char array.

Simply we can convert u32string to a wstring as below ( Thank you Remy Lebeau ),

std::u32string str32 = U"This is a u32string";
    std::wstring wstr = std::wstring( str32.begin(), str32.end() );

    std::wcout << "wstring: " << wstr << std::endl;

Or, we can create our u32string_to_wstring() method as described below.

std::wstring u32string_to_wstring (const std::u32string& str)
{
	return std::wstring(str.begin(), str.end());
}

We can use this conversion function like so:

std::u32string str32 = U"This is a u32string";
    std::wstring wstr = u32string_to_wstring(str32);

    std::wcout << "wstring: " << wstr << std::endl;

the output for both options will be:

wstring: This is a u32string

How can we correctly convert u32string to a wstring in C++?

There is another way to convert them by using std::wstring_convert and std::codecvt_utf16 templates. We can use the std::wstring_convert class template to convert a u16string to a wstring. The wstring_convert class template converts byte strings to wide strings using an individual code conversion tool, Codecvt These standard tools are suitable for use with the std::wstring_convert. We can use these with:

  • std::codecvt_utf8 for the UTF-8/UCS2 and UTF-8/UCS4 conversions
  • std::codecvt_utf8_utf16 for the UTF-8/UTF-16 conversions.

Note that codecvt_utf16 and wstring_convert are deprecated in C++17 and removed in C++26 and there is no better solution for Windows since they are not removed in most C++ compilers which means we can use them before C++26.

Syntax of std::wstring_convert class template (deprecated in C++17),

template< class Codecvt,
          class Elem = wchar_t,
          class Wide_alloc = std::allocator<Elem>,
          class Byte_alloc = std::allocator<char> >
class wstring_convert;

Syntax of std::codecvt_utf8 class template (deprecated in C++17):

template< class Elem,
          unsigned long Maxcode = 0x10ffff,
          std::codecvt_mode Mode = (std::codecvt_mode)0 >
class codecvt_utf16 : public std::codecvt<Elem, char, std::mbstate_t>;

In other way, we can use the following code (thank you Remy Lebeau ).

std::wstring u32string_to_wstring (const std::u32string& str)
{
	
    #ifdef MSWINDOWS

	std::wstring_convert<std::codecvt_utf16<char32_t>, char32_t> conv;
	std::string bytes = conv.to_bytes(str);
	return std::wstring(reinterpret_cast<const wchar_t*>(bytes.c_str()), bytes.length()/sizeof(wchar_t));

    #else

	return std::wstring(str.begin(), str.end());
    #endif
}

In my tests, std::wstring(str.begin(), str.end()) runs well on Windows with bcc32, bcc64, and with the latest Windows Modern 64-bit bcc64x compilers. But #ifdef MSWINDOWS ... #else part is recommended for some better conversions on Windows. Please check which one is suitable for your compiler.

How can we convert wstring to u32string in C++?

If you are looking conversion from wstring to u32string, here is how we can assign it in two different ways,

std::wstring wstr = L"This is a wstring";
    std::u32string str32;

    str32.assign( wstr.begin(), wstr.end());
    // or
    str32 = std::u32string( wstr.begin(), wstr.end() );

Is there a full example of how to convert u32string to a wstring in C++?

Here is a full example that converts a u32string to a wstring,

#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
#include <algorithm>

std::wstring u32string_to_wstring (const std::u32string& str)
{

    #ifdef MSWINDOWS

	std::wstring_convert<std::codecvt_utf16<char32_t>, char32_t> conv;
	std::string bytes = conv.to_bytes(str);
	return std::wstring(reinterpret_cast<const wchar_t*>(bytes.c_str()), bytes.length()/sizeof(wchar_t));

	#else

	return std::wstring(str.begin(), str.end());

	#endif
}

int main()
{
    std::u32string str32 = U"This is a u32string";

    //Converting u32string to wstring
    std::wcout << L"Converting u32string to wstring ..." << std::endl;
    std::wstring wstr = std::wstring(str32.begin(), str32.end());
    std::wcout << L"wstring: " << wstr << std::endl;
    // or we can print directly as a wstring
    std::wcout << L"wstring: " <<  std::wstring(str32.begin(), str32.end()) << std::endl;

    // or we can use our function as below
    std::wstring ws = u32string_to_wstring(str32);
    std::wcout << L"wstring: " <<  ws << std::endl;

    // Listing all characters
    for(int i=0; i<wstr.length(); ++i)
    {
        std::wcout << wstr[i] << " - " << (int)wstr[i] << std::endl;
    }

    // Converting wstring to u32string
    std::wcout << L"Converting wstring to u32string ..." << std::endl;
    str32.assign( wstr.begin(), wstr.end());
    std::wcout << L"wstring: " <<  std::wstring(str32.begin(), str32.end()) << std::endl;
    // or
    str32 = std::u32string( wstr.begin(), wstr.end() );
    std::wcout << L"wstring: " <<  std::wstring(str32.begin(), str32.end()) << std::endl;

    system("pause");
    return 0;
}

Here is the output.

Converting u32string to wstring ...
wstring: This is a u32string
wstring: This is a u32string
wstring: This is a u32string
T - 84
h - 104
i - 105
s - 115
  - 32
i - 105
s - 115
  - 32
a - 97
  - 32
u - 117
3 - 51
2 - 50
s - 115
t - 116
r - 114
i - 105
n - 110
g - 103
Converting wstring to u32string ...
wstring: This is a u32string
wstring: This is a u32string
How To Convert u32string To A wstring In C++. C++ Builder logo

C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.

There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise versions of C++ Builder and there is a trial version you can download from here.

The post How To Convert u32string To A wstring In C++ first appeared on Learn C++.]]>
9123
How To Learn The Move Constructors In Modern C++? https://learncplusplus.org/how-to-learn-the-move-constructors-in-modern-c/ Thu, 13 Jun 2024 05:00:00 +0000 http://learncplusplus.org/?p=4557 Object Oriented Programming in C++ is greatly strengthened by the new standards of modern C++. One of the features of modern C++ is the move constructor that allows you to move the resources from one...

The post How To Learn The Move Constructors In Modern C++? first appeared on Learn C++.]]>
Object Oriented Programming in C++ is greatly strengthened by the new standards of modern C++. One of the features of modern C++ is the move constructor that allows you to move the resources from one object to another object without copying them. In this post, we list the move constructor types that we are using in modern C++.

What is a constructor in C++?

The Constructor in C++ is a function, a method in the class, but it is a ‘special method’ that is automatically called when an object of a class is created. We don’t need to call this function. Whenever a new object of a class is created, the Constructor allows the class to initialize member variables or allocate storage. This is why the name Constructor is given to this special method. Here is a simple constructor class example below,

class myclass
{         
  public:   
    myclass()
    {
       std::cout << "myclass is constructed!\n";
    };
};

What is a move constructor in C++?

There are different constructor types in C++ Classes and the Move Constructor is one of these. Move Constructors not only used in classes but also used with struct and union data types. The Move Constructor is a constructor that allows you to move the resources from one object to another object without copying them. In other words, the move constructor allows you to move the resources from an rvalue object into to an lvalue object.

The Move Constructor of class T is a non-template constructor whose first parameter is class_name&&const class_name&&, volatile class_name&&, or const volatile class_name&&. It can be used with no other parameters or with the rest of the parameters all have default values.

This general syntax is also a syntax for the “Typical declaration of a move constructor” as in below,

class_name (class_name &&)

Syntax to use Move Constructor,

class_name ( class_name && ) // Declaration
{ // Definition
} // Definition

For more details about this please see this below,

Object Oriented Programming in C++ is highly evolved by the new standards of modern C++. One of the features of modern C++ is the move constructor that allows you to move the resources from one object to another object without copying them. In this post, we list the move constructor types in modern C++

What are the move constructors used in C++?

Now let’s see move constructors used in C++,

Typical declaration of a move constructor

The typical declaration of a move constructor is a move constructor declaration method that has user defined declaration and definition parts, and this is how you can declare typical move constructor in a class.

An example with a class;

class Tx
{
  public:
  Tx() = default; // Default Constructor
 
  Tx(Tx&& other) // A Typical Declaration of a Move Constructor
  {
  }
}

We can use move constructor with std::move as in example below.

class Tx o1;
class Tx o2 = std::move(o1);    // Using Move Constructor with std::move

For more details about this please see this below,

Default (forced) move constructor in modern C++

The default (forced) move constructor is a move constructor deceleration method that has forced by = default option. This default option is forcing a move constructor to be generated by the compiler, here is how you can do forcing move constructor in a class.

class Tx
{
  public:
  std::string str;
 
  Tx() = default; // Default Constructor
 
  Tx(Tx&& other) = default; // Default (Forced) Move Constructor
 
};

For more details about this feature please see this post below,

Trivial move constructor

The Trivial Move Constructor is a Move Constructor which is implicitly defined or defaulted and has no virtual member functions, no base classes. The trivial move constructor generally a constructor that comes from template class or base class. The move constructor selected for every direct base of T or for every non-static class type (including array of class type) of T is trivial move constructor.

In general, the trivial move constructor is a constructor that makes a copy of the object representation by using std::memmove, it operates like the trivial copy constructor. Note that, all POD data types (data types compatible with the C language) are trivially movable.

In modern C++ example, this simple Tx class has a move constructor.

class Tx
{
  public:
     std::string str = "LearnCPlusPlus.org";
 
};

Now, we can define a new Ty class and we can use Tx class as a base class as below.

class Ty : public class Tx  // uses Tx as a base class
{
  public:
 void print_str(){ std::cout << str << std::endl; }
 
 // This class has Trivial Move Constructor from Tx class
};

As you see, this new Ty class above has a trivial move constructor from Tx class. Because it is implicitly defined or defaulted.

For more details about this feature please see this post below,

Eligible move constructor

Since C++11, the Eligible Move Constructor is a Move Constructor which is eligible if it is not deleted. This definition is changed after C++20, the Eligible Move Constructor is a Move Constructor which is eligible if it is not deleted, if it has any associated constraints that are satisfied, if it has no move constructor with the same first parameter type is more constrained.

Until C++20, the move constructor is eligible:

  • if it is not deleted

Since C++20, the move constructor is eligible:

  • if it is not deleted,
  • and if it has any associated constraints that are satisfied
  • and it has no move constructor with the same first parameter type that is more constrained.

A simple class has an eligible move constructor because it has a default move constructor that compiler automatically defines, in Modern C++ it is similar as below.

class Tx
{
  public:
   std::string str = "LearnCPlusPlus.org";
 
   Tx() = default; // Constructor
 
   Tx(Tx&& other) = default; // Move Constructor
};

Now, we can define a new Ty class and we can use one of Tx classes above as a base class here.

class Ty : public class Tx  // uses Tx as a base class
{
  public:
 void print_str(){ std::cout << str << std::endl; }
 
 // This class has Eligible Constructor from Tx class
};

Deleted move constructor

Assume that there is a Tx class example with a declared and defined move constructor that uses std::move. We can delete this move constructor as below.

class Tx
{
  public:
   std::string str;
 
   Tx() = default; // Constructor
 
   Tx(Tx&& other) = delete;  // Deleted Move Constructor
};

Implicitly deleted move constructor

Now, we can define a new Ty class and we can use Tx class as a base class as below.

class Ty : public class Tx  // uses Tx as a base class
{
  public:
 void print_str(){ std::cout << str << std::endl; }
 
 // This class has Implicitly-deleted Move Constructor from Tx class
};

Deleted Implicitly-declared Move Constructor

As you can see deleted move constructors above, this Ty class above has the implicitly-deleted move constructor from Tx class. We cannot use a move constructor with std::move as in example below:

class Ty o1;
 
// class Ty o2 = std::move(o1); // ERROR : call to implicitly-deleted copy constructor of 'class Ty'

Here o2 can not be declared by std::move because Ty has Tx class which has deleted move constructor.

For more details about this feature please see this post below,

Implicitly-declared move constructor

The implicitly-declared move constructor in modern C++ is a move constructor that is declared implicitly by using the move constructor of another base class. In other terms you have a new class that uses the base class, this class has implicitly declared a move constructor from the base class.

Let’s give a simple C++ example of an implicitly-declared move constructor which is a move constructor of other base class. Let’s assume that we have Tx as a base class and we have a new Ty class. This new class can use the move constructor from the Tx. Here is a Tx class example with a declared and defined move constructor that uses std::move,

class Tx
{
  public:
   std::string str;
 
   Tx() = default; // Constructor
 
   Tx(Tx&& other)  // Declared Move Constructor
   {
 str = std::move(other.str);
   }
};

As given here above, if you have a move constructor, you should define a Constructor too, otherwise you will have “No matching constructor for initialization of class” error in compilation. Now, we can define a new Ty class and we can use Tx class as a base class as below.

class Ty : public class Tx  // uses Tx as a base class
{
  public:
 void print_str(){ std::cout << str << std::endl; }
 
 // This class has Implicitly-declared Move Constructor from Tx class
};

For more details about this feature please see this post below,

Implicitly-defined move constructor

The Implicitly-defined Move Constructor is a Move Constructor which is implicitly defined by another base, or it is an implicitly-declared move constructor neither deleted nor trivial.

  • The Implicitly-defined Move Constructor is defined, which means it has a function body with { } that is generated and compiled by the compiler implicitly.
  • The implicitly-defined move constructor performs full move operations on its members if it is a class or struct type.
  • The implicitly-defined move constructor copies the object representation (as in std::memmove) if it is a union type.

We can define our own move constructor as shown here:

class Tx
{
  public:
   std::string str = "LearnCPlusPlus.org";
 
   Tx() = default; // Constructor
 
   Tx(Tx&& other)                 // Move Constructor Declaration
   {                              // Move Constructor Definition
 str = std::move(other.str); // Move Constructor Definition
   }                              // Move Constructor Definition
 
};

And, we can use this Tx class as base class to define a new Ty class as below.

class Ty : public class Tx  // uses Tx as a base class
{
  public:
 void print_str(){ std::cout << str << std::endl; }
 
 // This class has Implicitly-defined Move Constructor from Tx class
};

For more details about this feature please see this post below,

Note that this struct can be used in C applications too. As you see, in modern C++, we can easily read WAV wave files, now you can display or edit wave files.

How To Learn The Move Constructors In Modern C++? C++ Builder logo

C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.

There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise version.

The post How To Learn The Move Constructors In Modern C++? first appeared on Learn C++.]]>
4557
How To Convert Char Array String To Unicode String Correctly In C++? https://learncplusplus.org/how-to-convert-char-array-string-to-unicode-string-correctly-in-c/ Tue, 11 Jun 2024 05:00:00 +0000 https://learncplusplus.org/?p=20118 I think one of the biggest problems in C++ today is there’s no perfect library to do conversions between strings in a global locale distribution. There are most problems when displaying or converting some characters...

The post How To Convert Char Array String To Unicode String Correctly In C++? first appeared on Learn C++.]]>
I think one of the biggest problems in C++ today is there’s no perfect library to do conversions between strings in a global locale distribution. There are most problems when displaying or converting some characters in most languages. Moreover, there are more conversion problems between UTF8, UTF16, and UTF32 strings. There are solutions but I found them not modern and simple as in today’s programming world. The UnicodeString is one of the most powerful string formats in use roday. A few weeks ago, I saw that char* arrays of a struct had some conversion problems when I read them from a file and displayed them in a TMemo box. In this post, I want to give you an example of how you can convert this kind of char* array to a Unicode String cxorrectly.

What is a string? a basic_string? and UnicodeString?

The basic_string (std::basic_string and std::pmr::basic_string) is a class template that stores and manipulates sequences of alpha numeric string objects (char, w_char,…). A basic string can be used to define string, wstring, u8string, u16string and u32string data types.

The UnicodeString string type is a default String type of RAD Studio, C++ Builder, Delphi that is in UTF-16 format that means characters in UTF-16 may be 2 or 4 bytes. In C++ Builder and Delphi; Char and PChar types are now WideChar and PWideChar, respectively. There is a good article about Unicode in RadStudio. And here is a good post about Basic String and Unicode String.

How to convert char array string to UnicodeString correctly in C++?

Assume that we have a struct with some char arrays, such as an example header as below,

struct Twavheader
{
   char format[4];
   char fmt[3];
   char c;
} wav = { 'W', 'A', 'V', 'E',
          'f', 'm', 't',
          '\0'  };

When we read this from a file, you should obtain char array properties correctly, such as chunk_ID, format, etc.They have nul terminator, so when we obtain and display these types we may have wrong outputs. To avoid this, there are 3 different solutions.

1. How to convert char string array to UnicodeString in a single line in C++?

In C++ Builder, UnicodeString type is really awesome in all the ways when you want to use strings. We can convert char string array to Unicode string in a single line in 3 different ways.

First, we can use this syntax to convert a char array in structs, or a char* array. (Thank You Remy Lebeau, Embarcadero MVP)

UnicodeString(const char* src, int len);

We can use this as below,

UnicodeString ustr =  UnicodeString( wav.format, 4 );

or we can define as below,

UnicodeString ustr( wav.format, 4 );

then we can display it in our Memo component as below,

Memo1->Lines->Add("File Format:" + ustr);

2. How can we use printf method of UnicodeString to convert char string array in a single line in C++?

Second, we can use printf() method of UnicodeString. Here we should use “%.4hs” format specifier as below,

UnicodeString ustr;
ustr.printf("%.4hs",  wav.format );

Here above, the .printf() method of System::UnicodeString takes a wide format string, and we are passing wav.format which is narrow string. When we are going to use wide printf with narrow inputs, then we should use “%hs" format specifier. The h tells printf that we are using narrow data in a context that expects wide. Likewise, we would use %ls when you are sending wide data to a version of printf that expects %s to mean narrow. ( Thank you Bruneau Babet, Embarcadero Developer)

3. How to convert char string array to UnicodeString using with std::string in C++?

Third, If you want to do this using with std::string, you can write as below,

UnicodeString ustr =  String( std::string(wav.format, 4).c_str() );

You can do same line step by step. First you should convert this format to std::string as below, note that that has 4 bytes size,

std::string str = std::string(wav.format, 4);

Now you can convert it to const char * as below,

const char* c_str = str.c_str();

Finally, you can safely convert char* to UnicodeString as below,

UnicodeString ustr =  String( c_str() );

Why other methods are not correct?

Assume that we read a wave file info in a struct, and we try to display some of the members of this struct in a Memo component. Let’s do this in 4 different ways. Compiler will compile all these lines below correctly but the outputs will be different.

UnicodeString str;

str.printf(L"a-File Format: %.4s", wav.format );              					 Memo1->Lines->Add(str);
str.printf(L"b-File Format: %.4ls", wav.format );                                Memo1->Lines->Add(str);
str.printf(L"c-File Format: %.4hs", wav.format );                                Memo1->Lines->Add(str);

str= "d-File Format: "+ String( wav.format );							         Memo1->Lines->Add(str);
str= "e-File Format: "+ String( std::string(wav.format).c_str() );             	 Memo1->Lines->Add(str);
str= "f-File Format: "+ String( std::string(wav.format, 4).c_str() );            Memo1->Lines->Add(str);
str= "g-File Format: "+ UnicodeString(wav.format, 4);            				 Memo1->Lines->Add(str);

Normally output of wav.format should be “WAVE“, here are the outputs what will they look like,

a-File Format: 䅗䕖浦⁴
b-File Format: 䅗䕖浦⁴
c-File Format: WAVE
d-File Format: WAVEfmt 
e-File Format: WAVEfmt 
f-File Format: WAVE
g-File Format: WAVE

From these outputs above,

  • As you see only we can obtain data and display it correctly as in (c), (f) and (g) lines.
  • (a) and (b) fails because, printf member of System::UnicodeString takes a wide format string, while it expects %s to also be wide we are using narrow wav.format.
  • (d) and (e) fails because of the no nul terminate the input in format. So the logic picks the next property fmt that happens to follow the WAVE. Luckly there is a "\0" nul terminate after the f,m, t characters and it stops there.

Is there an example to convert char string array to UnicodeString correctly in C++?

Here is a full example about to convert char string array to UnicodeString in C++ Builder,

//---------------------------------------------------------------------------
#include <fmx.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm1 *Form1;

#include <iostream>
#include <string>

struct Twavheader
{
   char format[4];
   char fmt[3];
   char c;
} wav = { 'W', 'A', 'V', 'E',
          'f', 'm', 't',
          '\0'  };

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) 	: TForm(Owner)
{

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  UnicodeString ustr(wav.format, 4) ; // CORRECT
  Memo1->Lines->Add( "File Format: "+ ustr);

  ustr.printf(L"%.4hs", wav.format); // CORRECT
  Memo1->Lines->Add( "File Format: "+ ustr);

  ustr= String( std::string(wav.format, 4).c_str() ); // OKAY
  Memo1->Lines->Add( "File Format: "+ ustr);
}//---------------------------------------------------------------------------
How To Convert Char Array String To Unicode String Correctly In C++?

C++ Builder is the easiest and fastest C and C++ compiler and IDE for building simple or professional applications on the Windows operating system. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for UIs.

There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise versions of C++ Builder and there is a trial version you can download from here.

The post How To Convert Char Array String To Unicode String Correctly In C++? first appeared on Learn C++.]]>
20118
How To Develop A Simple Hopfield Network In C++ https://learncplusplus.org/how-to-develop-a-simple-hopfield-network-in-c/ Tue, 04 Jun 2024 05:00:00 +0000 https://learncplusplus.org/?p=4877 In the history of AI development, one of the greatest AI technologies was the pattern recognition models, especially to read texts from pixel images. One of them was the Hopfield network (or Ising model of a...

The post How To Develop A Simple Hopfield Network In C++ first appeared on Learn C++.]]>
In the history of AI development, one of the greatest AI technologies was the pattern recognition models, especially to read texts from pixel images. One of them was the Hopfield network (or Ising model of a neural network or Ising–Lenz–Little model), which is a form of recurrent neural network, it was invented by Dr. John J. Hopfield in 1982. A Hopfield Network can be applied to pattern recognition, such as recognition from digit character images. In this post, we will develop a simple Hopfield Network example in GUI form using C++ Builder that can learn from pixelated patterns and we can recall them by testing some closest patterns.

What is Hopfield Network in AI development?

The purpose of a Hopfield Network is to store data patterns and to recall the full data pattern based on partial input. For example, a Hopfield Network can be applied to 8×8 digit character recognition from pixels. We can train some characters on this network and then we can ask a closer drawing character if it remembers trained one or not. We can use this Hopfield network to extract the characters from images and put them in a text file in ASCII form, which is called pattern recognition. The good behavior of this network is it can also remember the full form of that character while it is not given completely. This example can be used for the optical character recognition from a text and if there is deformation on a small part of a letter or on a paper, maybe be paper is dirty Hopefield network can remember this kind of problem. In new modern ML and AI applications, there are much more useful methods that are based on this Hopfield Network like Recurrent Artificial Neural Networks.

The Hopfield Network (or Ising model of a neural network or Ising–Lenz–Little model) is a form of recurrent neural network, and it was invented by Dr. John J. Hopfield in 1982. It consists of a single layer that contains one or more fully connected recurrent neurons. The Hopfield network is commonly used for auto-association and optimization tasks. Hopfield networks serve as content-addressable memory systems with binary threshold nodes. Hopfield networks also provide a primitive model for understanding how the human brain and memory can be simulated artificially.

How to Train a Hopfield Network

How we can apply this method on a digital character recognition in programming ? There is a way a Hopfield network would work on 1 and 0 pixels. We can map it out that each pixel represents one node in the Hopfield network. We can train correct form of the characters on this network to recognize each of characters. Hopfield network finds the most possible assumed character after few iterations, and eventually reproduces the pattern with the trained correct form. If we have N pixels, it means our network has NxN weights, so the problem is very computationally expensive and may be slow in some cases. In example, we can train blank form (space) and this “A” form, and so on.

All the nodes in a Hopfield network are used as both inputs and outputs, and they are fully interconnected with each other. That is, each node is an input to every other node in the network. We can think of the links from each node to itself as being a link with a weight of 0.


We can easily train Hopfield networks, we just need binary data to train this network. As we know we can have binary input vectors as well as bipolar input vectors. During the training of the Hopfield network, weights are being updated in iterations.

For example for a 3 node Hopefield network data matrix a composed with N elements and weight matrix composed with NxN elements. Here is a 3 node example to these matrixes,

How can we develop a simple Hopfield Network in C++?

Let’s create a simple Hofield Network C++ Builder example as below.

We can create a simper THopfield_Network class as in given steps below. Here is how we start to define out class,

class THopfield_Network
{  
  private:
    std::vector<std::vector<int>> weights;  
    
  public:
    THopfield_Network(int numofNeurons) : weights(numofNeurons, std::vector<int>(numofNeurons, 0))
    {
    }
}

We will add 3 public methods to this class. First, it will learn from a pattern vector by using learn_pattern() method which is defined as below,

// Learn from a pattern (update weights)
    void learn_pattern(const std::vector<int>& pattern)
    {
        for (int i = 0; i < pattern.size(); ++i)
        {
            for (int j = 0; j < pattern.size(); ++j)
        	{
                if (i != j)
                {
                    weights[i][j] += pattern[i] * pattern[j];
                }
            }
        }
    }

And we will update neurons of our hopfield network by using update_neuron() method which is defined as below,

// Update neuron asynchronously
    int update_neuron(const std::vector<int>& input, int neuronIndex)
    {
        int sum = 0;
        for (int i = 0; i < input.size(); ++i)
        {
            sum += weights[neuronIndex][i] * input[i];
        }
        return (sum >= 0) ? 1 : -1;
    }

We can use this update_neuron method to test given input pattern by using a test() method which is defined as below,

// Test the network
    std::vector<int> test(const std::vector<int>& input)
    {
        std::vector<int> output(input);
        for (int i = 0; i < input.size(); ++i)
        {
            output[i] = update_neuron(output, i);
        }
        return output;
    }

As a result our simple Hopfield Network class in modern C++ will be as below,

class THopfield_Network
{      
  private:
    std::vector<std::vector<int>> weights;   
    
  public:
    THopfield_Network(int numofNeurons) : weights(numofNeurons, std::vector<int>(numofNeurons, 0))
    {
    }

    // Learn from a pattern (update weights)
    void learn_pattern(const std::vector<int>& pattern)
    {
        for (int i = 0; i < pattern.size(); ++i)
        {
            for (int j = 0; j < pattern.size(); ++j)
        	{
                if (i != j)
                {
                    weights[i][j] += pattern[i] * pattern[j];
                }
            }
        }
    }

    // Update neuron asynchronously
    int update_neuron(const std::vector<int>& input, int neuronIndex)
    {
        int sum = 0;
        for (int i = 0; i < input.size(); ++i)
        {
            sum += weights[neuronIndex][i] * input[i];
        }
        return (sum >= 0) ? 1 : -1;
    }

    // Test the network
    std::vector<int> test(const std::vector<int>& input)
    {
        std::vector<int> output(input);
        for (int i = 0; i < input.size(); ++i)
        {
            output[i] = update_neuron(output, i);
        }
        return output;
    }  
};

Now we can globally define a hopfield network for given Width and Height pixels. In example if we have 6×6 pixels patterns we can define it as in below,

int W = 6, H = 6;

THopfield_Network hopfield(W*H);

Now we can define a pattern vector as below,

std::vector<int> pattern = {
        1, -1, -1, -1, -1, -1,
        -1, 1, -1, -1, -1, -1,
        -1, -1, 1, -1, -1, -1,
        -1, -1, -1, 1, -1, -1,
        -1, -1, -1, -1, 1, -1,
        -1, -1, -1, -1, -1, 1
    };

we can train this pattern and if we have another input pattern as above, we can test it to obtain closest result (recovered_pattern) to given input as below.

hopfield.learn_pattern(pattern);

std::vector<int> recovered_pattern = hopfield.test(input_pattern);

Now, let’s do all this with GUIs in C++ Builder.

How can we develop a simple Hopfield Network in C++ Builder?

  1. First, create a new C++ Builder FMX application, add an Image (TImage), Memo (TMemo) and 3 Buttons (TButton) which are “Clear”, “Train” and “Test” buttons. You can add some Layouts to arrange them as given Form (TForm) design below.

2. Add our THopfield_Network class to below the line “TForm1 *Form1;”,

3. Define bmp and bmp2 bitmaps as in this Form unit’s header file as below, bmp will be used as an input pattern. bmp2 will be displayed bitmap on Image.

class TForm1 : public TForm
{
__published:	// IDE-managed Components
	TImage *Image1;
	TButton *btTrain;
	TButton *btTest;
	TButton *btClear;
	TMemo *Memo1;
	TLayout *Layout1;
	TLayout *Layout2;
	void __fastcall btClearClick(TObject *Sender);
	void __fastcall Image1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, float X, float Y);
	void __fastcall btTrainClick(TObject *Sender);
	void __fastcall btTestClick(TObject *Sender);
private:	// User declarations
public:		// User declarations
	TBitmap *bmp, *bmp2;
	__fastcall TForm1(TComponent* Owner);

};

4. Now we can create these bitmaps when the Form is constructed as below.

__fastcall TForm1::TForm1(TComponent* Owner)  : TForm(Owner)
{
   bmp = new TBitmap(W,H);

   bmp2 = new TBitmap(Image1->Width, Image1->Height);
   Image1->Bitmap->Assign(bmp2);
}

5. Now we can create clear event by double clicking to Clear button, such as,

void __fastcall TForm1::btClearClick(TObject *Sender)
{
    bmp->Clear(claBlack);
    Image1->Bitmap->Clear(claBlack);
}

6. We should allow user to define its own pattern by clicking on the Image, so user can draw some patterns on our Image1. We can create this by double clicking OnMouseDown event as below,

void __fastcall TForm1::Image1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, float X, float Y)
{
    float w = Image1->Width/W; // grid width
    float h = Image1->Height/H; // grid height

    int px = X/w; // exact pixel X on the bitmap of scaled image
    int py = Y/h; // exact pixel Y on the bitmap of scaled image

    TBitmapData bitmapData;
    TAlphaColorRec acr;

    if( bmp->Map(TMapAccess::ReadWrite, bitmapData)) // Lock bitmap and retrive bitmap data
    {
		acr.Color = bitmapData.GetPixel( px, py );
        if(acr.Color == claBlack)
        {
            bitmapData.SetPixel(px,py, claWhite);
            Image1->Bitmap->Canvas->BeginScene();
            Image1->Bitmap->Canvas->Fill->Color  = claWhite;
            Image1->Bitmap->Canvas->FillRect( TRectF(px*w,py*h, px*w+w,py*h+h), 0, 0, AllCorners, 255.0);
            Image1->Bitmap->Canvas->EndScene();
        }
        else
        {
            bitmapData.SetPixel(px,py, claBlack);
            Image1->Bitmap->Canvas->BeginScene();
            Image1->Bitmap->Canvas->Fill->Color  = claBlack;
            Image1->Bitmap->Canvas->FillRect( TRectF(px*w,py*h, px*w+w,py*h+h), 0, 0, AllCorners, 255.0);
            Image1->Bitmap->Canvas->EndScene();
        }

        bmp->Unmap(bitmapData);
    }

}

7. Now, we can create training method by double clicking our Train button. In this method, we will read data from pixels of bmp bitmap then we will display this in Memo box, and then we will learn this pattern by using hopfield.learn_pattern(pattern); Here is how we do this below,

void __fastcall TForm1::btTrainClick(TObject *Sender)
{
    std::vector<int> pattern;

    TBitmapData bitmapData;
    TAlphaColorRec acr;

    if( bmp->Map(TMapAccess::ReadWrite, bitmapData)) // Lock bitmap and retrive bitmap data
    {
        for(int j=0; j<H; j++)
        for(int i=0; i<W; i++)
        {
        	acr.Color = bitmapData.GetPixel( i, j );
        	if(acr.Color == claBlack) pattern.push_back(-1);
         	else pattern.push_back(1);
        }
        bmp->Unmap(bitmapData);
    }

    Memo1->Lines->Add("Learned Pattern:");
    for(int j=0; j<H; j++)
    {
    	String str ="";
        for(int i=0; i<W; i++)
      	{
            if(pattern[j*W+i]==1) str += "* ";
            				 else str += "  ";
        }
        Memo1->Lines->Add(str);
    }

    Memo1->Lines->Add("------------");
    hopfield.learn_pattern(pattern);
}

8. Finally we can create Testing event by double clicking to Test button.

void __fastcall TForm1::btTestClick(TObject *Sender)
{
    std::vector<int> pattern;

    TBitmapData bitmapData;
    TAlphaColorRec acr;

    if( bmp->Map(TMapAccess::ReadWrite, bitmapData)) // Lock bitmap and retrive bitmap data
    {
        for(int j=0; j<H; j++)
        for(int i=0; i<W; i++)
        {
        	acr.Color = bitmapData.GetPixel( i, j );
        	if(acr.Color == claBlack) pattern.push_back(-1);
         	else pattern.push_back(1);
        }
        bmp->Unmap(bitmapData);
    }


    std::vector<int> recoveredpattern = hopfield.test(pattern);

    float w = Image1->Width/W; // grid width
    float h = Image1->Height/H; // grid height

    Memo1->Lines->Add("Recovered Pattern:");

    Image1->Bitmap->Canvas->BeginScene();
    for(int j=0; j<H; j++)
    {
    	String str ="";

        for(int i=0; i<W; i++)
      	{
            if(recoveredpattern[j*W+i]==1)
            {
                Image1->Bitmap->Canvas->Fill->Color  = claWhite;
                Image1->Bitmap->Canvas->FillRect( TRectF(i*w, j*h, i*w+w, j*h+h), 0, 0, AllCorners, 255.0);
                str += "* ";
            }
            else
            {
                Image1->Bitmap->Canvas->Fill->Color  = claBlack;
                Image1->Bitmap->Canvas->FillRect( TRectF(i*w, j*h, i*w+w, j*h+h), 0, 0, AllCorners, 255.0);
                str += "  ";
            }
        }
        Memo1->Lines->Add(str);
    }

    Image1->Bitmap->Canvas->EndScene();
    Memo1->Lines->Add("------------");
}

How can we test a simple Hopfield Network app in C++ Builder?

Now we can run our application (F9). First, we can Clear and then we Train this blank pattern, then we can draw “A” as below and then we can Train this. You can train more different patterns.

After this step, we can ask another pattern by using Test button that looks like one of the pattern that we trained before, such as this,

As a result you will see that our Hopfield Network remembers its closest pattern and recovers it.

As you see developing AI technologies in C++ Builder is really easy and amazing to understand AI technologies that build helps to build today’s models.

Is there a full example C++ code about Hopfield Network in C++ Builder?

Here is the full example of C++ Builder FMX application, note that header is also given above,

//---------------------------------------------------------------------------

#include <fmx.h>
#include <vector>

#pragma hdrstop

#include "Hopfield_Network_FMX_Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm1 *Form1;

class THopfield_Network
{      
  private:
    std::vector<std::vector<int>> weights;   
    
  public:
    THopfield_Network(int numofNeurons) : weights(numofNeurons, std::vector<int>(numofNeurons, 0))
    {
    }

    // Learn from a pattern (update weights)
    void learn_pattern(const std::vector<int>& pattern)
    {
        for (int i = 0; i < pattern.size(); ++i)
        {
            for (int j = 0; j < pattern.size(); ++j)
        	{
                if (i != j)
                {
                    weights[i][j] += pattern[i] * pattern[j];
                }
            }
        }
    }

    // Update neuron asynchronously
    int update_neuron(const std::vector<int>& input, int neuronIndex)
    {
        int sum = 0;
        for (int i = 0; i < input.size(); ++i)
        {
            sum += weights[neuronIndex][i] * input[i];
        }
        return (sum >= 0) ? 1 : -1;
    }

    // Test the network
    std::vector<int> test(const std::vector<int>& input)
    {
        std::vector<int> output(input);
        for (int i = 0; i < input.size(); ++i)
        {
            output[i] = update_neuron(output, i);
        }
        return output;
    }  
};

int W = 6, H = 6;
THopfield_Network hopfield(W*H);

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)  : TForm(Owner)
{
   bmp = new TBitmap(W,H);

   bmp2 = new TBitmap(Image1->Width, Image1->Height);
   Image1->Bitmap->Assign(bmp2);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btClearClick(TObject *Sender)
{
    bmp->Clear(claBlack);
    Image1->Bitmap->Clear(claBlack);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Image1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, float X, float Y)
{
    float w = Image1->Width/W; // grid width
    float h = Image1->Height/H; // grid height

    int px = X/w; // exact pixel X on the bitmap of scaled image
    int py = Y/h; // exact pixel Y on the bitmap of scaled image

    TBitmapData bitmapData;
    TAlphaColorRec acr;

    if( bmp->Map(TMapAccess::ReadWrite, bitmapData)) // Lock bitmap and retrive bitmap data
    {
		acr.Color = bitmapData.GetPixel( px, py );
        if(acr.Color == claBlack)
        {
            bitmapData.SetPixel(px,py, claWhite);
            Image1->Bitmap->Canvas->BeginScene();
            Image1->Bitmap->Canvas->Fill->Color  = claWhite;
            Image1->Bitmap->Canvas->FillRect( TRectF(px*w,py*h, px*w+w,py*h+h), 0, 0, AllCorners, 255.0);
            Image1->Bitmap->Canvas->EndScene();
        }
        else
        {
            bitmapData.SetPixel(px,py, claBlack);
            Image1->Bitmap->Canvas->BeginScene();
            Image1->Bitmap->Canvas->Fill->Color  = claBlack;
            Image1->Bitmap->Canvas->FillRect( TRectF(px*w,py*h, px*w+w,py*h+h), 0, 0, AllCorners, 255.0);
            Image1->Bitmap->Canvas->EndScene();
        }

        bmp->Unmap(bitmapData);
    }

}
//---------------------------------------------------------------------------
void __fastcall TForm1::btTrainClick(TObject *Sender)
{
    std::vector<int> pattern;

    TBitmapData bitmapData;
    TAlphaColorRec acr;

    if( bmp->Map(TMapAccess::ReadWrite, bitmapData)) // Lock bitmap and retrive bitmap data
    {
        for(int j=0; j<H; j++)
        for(int i=0; i<W; i++)
        {
        	acr.Color = bitmapData.GetPixel( i, j );
        	if(acr.Color == claBlack) pattern.push_back(-1);
         	else pattern.push_back(1);
        }
        bmp->Unmap(bitmapData);
    }

    Memo1->Lines->Add("Learned Pattern:");
    for(int j=0; j<H; j++)
    {
    	String str ="";
        for(int i=0; i<W; i++)
      	{
            if(pattern[j*W+i]==1) str += "* ";
            				 else str += "  ";
        }
        Memo1->Lines->Add(str);
    }

    Memo1->Lines->Add("------------");
    hopfield.learn_pattern(pattern);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btTestClick(TObject *Sender)
{
    std::vector<int> pattern;

    TBitmapData bitmapData;
    TAlphaColorRec acr;

    if( bmp->Map(TMapAccess::ReadWrite, bitmapData)) // Lock bitmap and retrive bitmap data
    {
        for(int j=0; j<H; j++)
        for(int i=0; i<W; i++)
        {
        	acr.Color = bitmapData.GetPixel( i, j );
        	if(acr.Color == claBlack) pattern.push_back(-1);
         	else pattern.push_back(1);
        }
        bmp->Unmap(bitmapData);
    }


    std::vector<int> recoveredpattern = hopfield.test(pattern);

    float w = Image1->Width/W; // grid width
    float h = Image1->Height/H; // grid height

    Memo1->Lines->Add("Recovered Pattern:");

    Image1->Bitmap->Canvas->BeginScene();
    for(int j=0; j<H; j++)
    {
    	String str ="";

        for(int i=0; i<W; i++)
      	{
            if(recoveredpattern[j*W+i]==1)
            {
                Image1->Bitmap->Canvas->Fill->Color  = claWhite;
                Image1->Bitmap->Canvas->FillRect( TRectF(i*w, j*h, i*w+w, j*h+h), 0, 0, AllCorners, 255.0);
                str += "* ";
            }
            else
            {
                Image1->Bitmap->Canvas->Fill->Color  = claBlack;
                Image1->Bitmap->Canvas->FillRect( TRectF(i*w, j*h, i*w+w, j*h+h), 0, 0, AllCorners, 255.0);
                str += "  ";
            }
        }
        Memo1->Lines->Add(str);
    }

    Image1->Bitmap->Canvas->EndScene();
    Memo1->Lines->Add("------------");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
   bmp->Free();   
   bmp2->Free();
}
//---------------------------------------------------------------------------

What Is Assignment Operator Overloading? C++ Builder logo

C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.

There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise version.

The post How To Develop A Simple Hopfield Network In C++ first appeared on Learn C++.]]>
4877
Learn Default Constructors Of Classes In Modern C++ https://learncplusplus.org/learn-default-constructors-of-classes-in-modern-c/ Thu, 30 May 2024 05:00:00 +0000 http://learncplusplus.org/?p=4522 Classes in C++ are the main building blocks of Object Oriented Programming Tools. They have a special function known as a constructor which is automatically called when an object of a class is created. There...

The post Learn Default Constructors Of Classes In Modern C++ first appeared on Learn C++.]]>
Classes in C++ are the main building blocks of Object Oriented Programming Tools. They have a special function known as a constructor which is automatically called when an object of a class is created. There is a default constructor type in classes that is called when a class is defined with no arguments, or it is defined with an empty parameter list, or with default arguments provided for every parameter. In this post, we are listing here all default constructor types in C++ with detailed posts and examples for each of them.

What is a constructor in a modern C++ class?

The Constructor in C++ is a function, a method in the class, but it is a ‘special method’ that is automatically called when an object of a class is created. We don’t need to call this function. Whenever a new object of a class is created, the Constructor allows the class to initialize member variables or allocate storage. This is why the name Constructor is given to this special method. To create a Constructor, we should use the same name of the class, followed by ( and ) parentheses as below,

class myclass
{         
  public:   
    myclass()
    {
       std::cout << "myclass is constructed!\n";
    };
};

There are different constructor types and the Default Constructor in classes is one of these. This method not only used in classes but also used with struct and union data types Do you want to learn what is default constructor or what kind of methods we have that we can declare and use default constructors ? In this post, we will try to explain Default Constructor with examples.

What is a default constructor in a modern C++ class?

A Default Constructor is a constructor type in Classes that is called when class is defined with no arguments, or it is defined with an empty parameter list, or with default arguments provided for every parameter. A type with a public default constructor is DefaultConstructible;

In definition of a default Constructor, class_name must name the current class or current instantiation of a class template. It must be a qualified class name when declared at namespace scope or in a friend declaration.

How can we define and declare default constructors in modern C++?

Now, let’s see default constructor types in C++ with detailed posts and examples for each of them.

Here’s how to declare a Default Constructor inside of a C++ class definition

We can declare a default constructor inside of a class. Just add class name with ( and ) inside that class as below; create a method

Syntax,

class_name()
{
};

An example with a class;

class myclass
{         
  public:   
    myclass()
    {
    }
};

For more details and examples please see the following.

How to define the Default Constructor outside of a C++ Class Definition

We can define a default constructor outside of a class. Add a class name and ( ); inside the class also add class name and :: operator with class name and ( ) outside of that class as below,

Syntax,

class_name :: class_name()
{
// statement
}

An example with a class;

class myclass
{         
  public:   
    myclass();
};

myclass :: myclass() 
{ 

}

For more details and examples please check this below,

What is a Trivial Default Constructor in C++?

Trivial Default Constructor is a constructor that does not act. All data types compatible with the C are trivially default-constructible. Here is a simple class that includes trivial default constructor which is not seen inside.

class my_class
{
   // this class has trivial default constructor
};

For more details and examples please check this below,

What is an Eligible Default Constructor in C++?

A default constructor is eligible if it is either user-declared or both implicitly-declared and definable

class myclass
{         
  public:   
    myclass() // Eligible Default Constructor
    {
       std::cout << "myclass is constructed!\n";
    };
};

What is a Defaulted Default Constructor in C++?

We can define a defaulted default constructor in a class with = operator and default statement. Thus, the compiler will define the implicit default constructor even if other constructors are present.

Syntax,

class_name() = default;

An example with a class;

class myclass
{
  public:
	myclass()=default;
};

For more details and examples please check this below,

How do I use a Defaulted Default Constructor outside of a C++ Class definition?

We can easily default the Default Constructor by using = default; after class name with (); We can also do this outside of a Class Definition. The default statement means that you want to use the compiler-generated version of that function, so you don’t need to specify a body. We can also use = delete to specify that you don’t want the compiler to generate that function automatically.

Syntax,

class_name :: class_name() = default;

An example with a class;

class myclass
{
  public:
   myclass();
};

myclass::myclass() = default;

For more details and examples please check this below,

What is a Deleted Default Constructor in C++?

We can easily default the Default Constructor by using = default; after class name with (); We can do this outside of a Class Definition. The default statement means that you want to use the compiler-generated version of that function, so you don’t need to specify a body.

We can also use = delete to specify that you don’t want the compiler to generate that function automatically. In another way, = delete means that the compiler will not generate those constructors when declared and this is only allowed on copy constructor and assignment operator. 

There is also = 0 usage; it means that a function is purely virtual and you cannot instantiate an object from this class. You need to derive from it and implement this method. Thus, the term = 0 is not the same as the term = delete.

Syntax,

class_name() = delete;

An example with a class;

class myclass
{
  public:
   myclass() = delete;
};

For more details and examples please check this below,

What is an Implicitly Declared Default Constructor in C++?

In C++ programming, If there is no constructor in the class (in the struct or in the union), the C++ compiler will always declare a default constructor as an inline public member of that class. If there is a declared default constructor, we can force the automatic generation of a default constructor in a new class by the compiler that would be implicitly declared otherwise with the keyword default.

Here is an Implicitly-Declared Default Constructor example,

class my_class
{
  public:
   my_class()  // constructor
   {
   };
};
 
class my_other_class : my_class  
{
   // implicitly declared default constructor copied from the my_class
};

For more details and examples please check this below,

What is an Implicitly Defined Default Constructor in C++?

In C++ programming, If there is no constructor in the class (in the struct or the union), the C++ compiler will always declare a default constructor as an inline public member of that class. If there is a declared default constructor, we can force the automatic generation of a default constructor in a new class by the compiler that would be implicitly declared otherwise with the keyword default. We can also implicitly define (not ‘declare’) a default constructor in another class. If we define a constructor in a class, we can also use this class and its constructor in another class. The difference between the Implicitly Defined Default Constructor and Implicitly Declared Default Constructor is here we defined a new class member and still, our class has its default constructor while it can use the default constructor from its new class member.

Here is an Implicitly-Defined Default Constructor example,

class my_class
{
  public:
   my_class() //Default Constructor
   {
   };
};
 
class my_other_class 
{
  public:
    my_class test; // This class has Implicitly-Defined Default Constructor
};

For more details and examples please check this below,

What is a Deleted Implicitly-Declared Default Constructor in C++?

In C++ programming, if there is a declared default constructor, we can force the automatic generation of a default constructor in a new class by the compiler that would be implicitly declared otherwise with the keyword default. If we don’t define a constructor in a class and the implicitly-declared default constructor is not trivial, we can inhibit the automatic generation of an implicitly-defined default constructor by the compiler with the keyword delete.

Here is an Implicitly-Declared Default Constructor example that gives Error,

#include <iostream>
 
class my_class
{
  public:
 int start;
 my_class() = delete;
 /*
 {
    start=100;
 };   */
};
 
class my_other_class : public my_class
{
 public:
 //   my_class() = delete;
 //  my_class::my_class() = delete;  // implicitly declared default constructor copied from the my_class
};
 
int main()
{
 // Line below has Error: call to implicitly-deleted default constructor of 'my_other_class'
 my_other_class test;    // This class has Deleted Implicitly-Declared Default Constructor and
 
 std::cout << test.start ;  // Let's check if it worked same as the previously decleared one
 
 getchar();
 return 0;
}

For more details and examples please check this below,

You can use the search function to find more examples about constructors in C++ on LearnCPlusPlus.org

Learn Default Constructors Of Classes In Modern C++. C++ logo

C++ Builder is the easiest and fastest C and C++ compiler and IDE for building simple or professional applications on the Windows operating system. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for UIs.

There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise versions of C++ Builder and there is a trial version you can download from h

The post Learn Default Constructors Of Classes In Modern C++ first appeared on Learn C++.]]>
4522
How To Develop Special AI Activation Functions In C++? https://learncplusplus.org/how-to-develop-special-ai-activation-functions-in-c/ Tue, 28 May 2024 05:00:00 +0000 https://learncplusplus.org/?p=5100 Artificial Intelligence models in today’s AI development are rapidly increasing. These models execute and learn using mathematical functions that optimize the best result when it propagates or chooses the best solutions when it back propagates...

The post How To Develop Special AI Activation Functions In C++? first appeared on Learn C++.]]>
Artificial Intelligence models in today’s AI development are rapidly increasing. These models execute and learn using mathematical functions that optimize the best result when it propagates or chooses the best solutions when it back propagates between artificial neurons. One of these functions is the Activation Function. Also called a transfer function, or threshold function it determines the activation value of a neuron as an output that is calculated by the sum of weighted values from inputs. In this post, we describe the most used activation functions available today and show how they can be used in C++.

What is an AI activation function?

An Activation Function ( phi() ) also called a transfer function, or threshold function. It determines the activation value ( a = phi(sum) ) from a given value (sum) from the Net Input Function . In a Net Input Function, the sum is a sum of signals in their weights. The activation function is a new value of this sum with a given function or conditions. Activation function is a way to transfer the sum of all weighted signals to a new activation value of that signal. There are different activation functions, some common ones are Linear (Identity), bipolar and logistic (sigmoid).

In C++ you can create your own AI activation function. Note that ‘sum’ is the result of Net Input Function which calculates sum of all weighted signals. We will use sum as a result of input function. Here the activation value of an artificial neuron (output value) can be written by the Activation function as shown below,

By using this sum Net Input Function Value and phi() activation function, we can calculate the output.

How can we develop special activation functions in AI?

In AI development, there are different types of activation functions for different purposes. We can use them or we can develop a special activation function. Now let’s see activation function types in AI development.

1. Identity Function ( y=x )

An Identity Function, also called an Identity relation or Identity Map or Identity Transformation, is a function in mathematics that always returns the same value that was used as its argument. We can briefly say that it is a y=x function or f(x) = x function. This function can be also used as a activation function in some AI applications.

This is a very simple Activation Function which is also an Identity Function,

float phi(float sum)
{
  return sum ;   // Identity Function, linear transfer function f(sum)=sum
}

return value of this function should be floating number ( float, double, long double) because of weights are generally between 0 and 1.0,

2. Binary Step Function (Heaviside Step Function)

Binary Step Function , or Heaviside step function, or the unit step function, is a step function, named after Oliver Heaviside (1850–1925), the value of which is zero for negative arguments and one for positive arguments. That means it results 0 or 1 as a Boolean. This function is an example of the general class of step functions, all of which can be represented as linear combinations of translations of this one.

Thus, our Binary Step Function should be as shown below.

bool phi(float sum)
{
  return(sum>0) ;   // Binary Step Function , Heaviside Step Function, Unit Step Function,
}

This activation function returns 1 (true) if sum>0 otherwise returns 0 (false).

For more details and examples please check this post below.

3. Logistic Function (Logistic Curve) and Sigmoid Function

Logistic function or Logistic Curve is a common S-shaped curve (sigmoid curve) with equation below.

Here,
L is maximum value of curve,
x0 is the value of curves mid point,
k the logistic growth rate or steepness of the curve

The most used Logistic Function is a Standard Logistic Function which is known as Sigmoid Function, where L and k is 1 and x0=0. Thus our function can be written one of these terms as below,

and in C++ the Sigmoid activation function can be written as below:

double phi(double sum)
{
  return ( 1/(1+ std::exp( -1*sum)) );   //  Standard Logistic Function, Sigmoid Function
}

Note that here division costs more CPU usage than a multiplication, as in function given above we can use the version with tanh() like so:

double phi(double sum)
{
  return ( 0.5*(1+ std::tanh( 0.5*sum)) );   //  Standard Logistic Function, Sigmoid Function
}

As you see, we have only multiplication and addition with tanh() function here. If the network’s sum values are in a range i.e. between (0-10) , to achieve faster approximate results arrayed results can be used. There may be y array with 10000 members and for example y[1001] can hold pre-calculated value for phi(1.0001). This will make your neural network faster but also may cause more errors or hard to achieve desired epoch numbers. It should be tested with the one of the normal sigmoid function versions as above.

For more details and examples please check this post below,

4. Hyperbolic Tangent Function (tanh)

The hyperbolic tangent is a trigonometric function tanh() as below,

This function has the unique solution to the differential equation f ′ = 1 − f2, with f (0) = 0.

An Activation Function can be a used as a Hyperbolic Tangent Function as below,

double phi(double sum)
{
  return ( std::tanh(sum) );   //  Hiperbolic Tangent Function
}

For more details and examples please check this post below,

5. Exponential Linear Unit (ELU)

An Exponential Linear Unit (ELU) is another activation function which is developed and published by Djork-Arne Clevert, Thomas Unterthiner & Sepp Hochreiter with the title “FAST AND ACCURATE DEEP NETWORK LEARNING BY EXPONENTIAL LINEAR UNITS (ELUS)”. You can find the text of the paper by clicking here.

According to their study, they introduce the “exponential linear unit” (ELU) that it speeds up learning in deep neural networks and leads to higher classification accuracies. ELU activation function alleviate the vanishing gradient problem via the identity for positive values, like rectified linear units (ReLUs), leaky ReLUs (LReLUs) and parametrized .ReLUs (PReLUs),. They also proof that ELUs have improved learning characteristics compared to the units with other activation functions. In contrast to ReLUs

Exponential Linear Unit (ELU) can be written as below.

and derivative of this function can be written as:

In C & C++ Programming language, simply Exponential Linear Unit function can be written as below

double alpha = 0.1; // ranges from 0 to 1.0

double phi(double sum)
{
   return( sum>0? sum :  alpha*( std::exp(sum)-1) );   //  ELU Function
}

For more details and examples please check this post below,

6. Scaled Exponential Linear Unit (SELU)

The Scaled Exponential Linear Unit is another activation function which is a scaled version of ELU by using λ parameter. Scaled Exponential Linear Unit is developed and released with the “Self-Normalizing Neural Networks” paper by Günter Klambauer, Thomas Unterthiner, Andreas Mayr in 2017. They introduced self-normalizing neural networks (SNNs) to enable high-level abstract representations. Neuron activations of SNNs automatically converge towards zero mean and unit variance, while the batch normalization requires explicit normalization.

SELU is a scaled version of ELU activation function by multiplying with λ parameter, So we can simply say this,

The SELU Activation Function can be written as follows,

They have solved for α and λ and obtain the solutions α01 ≈ 1.6733 and λ01 ≈ 1.0507, where the subscript 01 indicates that these are the parameters for fixed point (0, 1). According this explanation, each node may have different α and λ parameters. So we can define alfa and lambda parameters in neuron structure and we can calculate SELU as below.

double phi(double sum)
{
   return( sum>0? lambda*sum :  lambda*alpha*( std::exp(sum)-1) );   //  SELU Function
}

For more details and examples please check this post below,

7. Rectified Linear Unit (ReLU)

In Artificial Neural Networks, the Rectifier Linear Unit Function or in other terms  ReLU Activation Function is an activation function defined as the positive part of its argument. Can be written as f(x)= max(0, x) where x is sum of weighted input signals to an artificial neuron. ReLU Function is also known as a Ramp Function and is analogous to Half-wave Rectification in electrical engineering.

This function called as a Parametric ReLU function. If Beta is 0.01 it is called Leaky ReLU function.

This is max-out ReLU function,

if Beta is 0 then f(x) = max(x, 0). This function will return always positive numbers. Let’s write maxout ReLU function in C programming language,

Here is the example,

double phi(double sum)
{
  return ( std::max(0, sum) );   //  ReLU Function
}

For more details and examples please check this post below,

8. Gaussian Error Linear Unit (GELU)

A Gaussian Error Linear Unit is an alternative to RELU, ELU functions, defined and published by Dan Hendrycks and Kevin Gimpel in 2016. It is used to smooth RELU and ELU activations (Full paper can be found here)

The Gaussian Error Linear Unit (GELU) is a high-performing neural network activation function. The GELU activation function is xΦ(x), where Φ(x) the standard Gaussian cumulative distribution function. The GELU nonlinearity weights inputs by their value, rather than gates inputs by their sign as in ReLUs (x1x>0). An empirical evaluation of the GELU nonlinearity against the ReLU and ELU activations has been applied and there is performance improvements across all considered computer vision, natural language processing, and speech tasks.

GELU function can be written as

We can approximate the GELU with,

or if greater feedforward speed is worth the cost of exactness we can use this approximation below,

We can use different CDFs, i.e we can use Logistic Function, Cumulative Distribution Function CDF σ(x) to obtain activation value, that is call the Sigmoid Linear Unit (SiLU) xσ(x).

From the second formula we can code our phi() activation function with GELU as below,

double sqrt_2divPI= std::sqrt(2.0/M_PI);

double phi(double sum)
{
    return( 0.5*sum*(1 + std::tanh( sqrt_2divPI*( sum + 0.044715*std::pow(sum,3)) ) ) );    //  GeLU Function
}

For more details and examples please check this post below,

9. SoftPlus Activation Function

The SoftPlus Activation Function is developed and published by Dugas et al in 2001. The full paper can be found here. Put simply, the Softplus function can be written as below,

f(x) = log( 1+exp(x) );

According to their paper; the basic idea of the proposed class of functions, they replace the sigmoid of a sum by a product of Softplus or sigmoid functions over each of the dimensions (using the Softplus over the convex dimensions and the sigmoid over the others). They introduced the concept that new classes of functions similar to multi-layer neural networks have those properties.

Another study published by Xavier Glorot, Antoine Bordes, Yoshua Bengio, the full paper is titled “Deep Sparse Rectifier Neural Networks” which can be found here. According to this study, in Artificial Neural Networks, while logistic sigmoid neurons are more biologically plausible than hyperbolic tangent neurons, the latter work better for training multi-layer neural networks.

A SoftPlus activation function in C++ can be written as below:

double phi(double sum)
{
  return ( std::log( 1+  exp(sum) ) );   //  SoftPlus Function
}

For more details and examples please check this post below,

10. Self Regularized Non-Monotonic (Mish) Activation Function

Self Regularized Non-Monotonic (Mish) Activation Function is inspired by the Swish activation function. It is a smooth, continuous, self-regularized, non-monotonic activation function. This function is published “Mish: A Self Regularized Non-Monotonic Activation Function” by Diganta Misra in 2019.

According to this study, “Mish uses the Self-Gating property where the non-modulated input is multiplied with the output of a non-linear function of the input. Due to the preservation of a small amount of negative information, Mish eliminated by design the preconditions necessary for the Dying ReLU phenomenon. This property helps in better expressivity and information flow. Being unbounded above, Mish avoids saturation, which generally causes training to slow down due to near-zero gradients drastically. Being bounded below is also advantageous since it results in strong regularization effects. Unlike ReLU, Mish is continuously differentiable, a property that is preferable because it avoids singularities and, therefore, undesired side effects when performing gradient-based optimization.”

We explained softplus() activation function before. Mish Activation Function can be defined by using softplus() as follows,

Hence, Mish Activation Function can be defined mathematically as follows,

Author compared well Mish, ReLU, SoftPlus and Swish activation function outputs and also compared first and second derivatives of Mish and Swish.

Mish function can be coded in C++ as below,

double phi(double sum)
{
  return ( sum* std::tanh( std::ln(1+ std::exp(sum)) );   //  Mish Function
}

For more details and examples please check this post below,

11. Softmax Function

In neural networks, the SoftMax function is often used in the final layer of a neural network-based classifier. Such these kinds of networks are generally trained under a log loss or cross entropy methods that are a non-linear variant of multinominal logistic regression. Softmax function is used to soft outputs between 0 and 1, it can be used as an activation function too.

For a x vector (or array) which has n members a Softmax for each member can be written as below,

This function may overflow due to infinitive results. To avoid this we can modulate x values by subtracting maximum value m.

For more details and examples please check this post below,

How To Develop Special AI Activation Functions In C++?

C++ Builder is the easiest and fastest C and C++ compiler and IDE for building simple or professional applications on the Windows operating system. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for UIs.

There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise versions of C++ Builder and there is a trial version you can download from here.

The post How To Develop Special AI Activation Functions In C++? first appeared on Learn C++.]]>
5100
Learn How To Read The WAV Waveform Audio File Format In C++ https://learncplusplus.org/learn-how-to-read-the-wav-waveform-audio-file-format-in-c/ Fri, 24 May 2024 05:00:00 +0000 https://learncplusplus.org/?p=5570 Sound is one of the important parts of computer science and programming. The correct use of sound can add excitement to recreational apps such as games or it can act to alert the user to an important event...

The post Learn How To Read The WAV Waveform Audio File Format In C++ first appeared on Learn C++.]]>
Sound is one of the important parts of computer science and programming. The correct use of sound can add excitement to recreational apps such as games or it can act to alert the user to an important event or state change in a utility or business-focused program. We have many different sound formats to play sound files in our applications or mostly in our games, or sometimes we need to edit them to analyze or to apply some filters. Games, MIDI Apps, Sound Editors, Music Studio Apps, Engineering Apps, AI Applications (such as voice recognition from sound or movie files), etc. Waveform Audio File Format (shortly *.WAVE or *.WAV files) are the oldest and they are still useful to play them from memory and it is easy to edit them. In this post, we explain how we can read the WAV Waveform Audio File Format in C++.

What is the WAV waveform audio file format in C++?

Audio files have different audio formats – ways of storing the analog sound in a variety of digital representations. The most used formats are MP3, OG, and FLAC files and these audio formats have compression techniques to make audio files smaller. The most known raw version is a WAV file. Wave format (*.wav or *wave) is a recorded digital form of sound whose volume changes data across a timeline. In C++ Builder it is easy to use recording wav files on Windows. To record a sound in Multi-Device applications we must use FMX.Media.hpp header.

How can we record a WAV waveform audio file format in C++?

Recording WAV sound is well explained in our Learn How To Easily Record Sound In Powerful Modern C++ On Windows post.

How can we read the WAV waveform audio file format in C++?

If you are reading a binary file, first you should know its structure type and so on. Waveform Audio File Format (WAVE or WAV) is an audio file format standard to record audio bitstream on a memory or on a drive as a file. Here are two images that show the header of the WAVE format.


How can we read the WAV waveform audio file format in C++?

WAW header can be defined as a structure as shown below:

// WAVE file header structure
struct Twavheader
{
    char chunk_ID[4];              //  4  riff_mark[4];
    uint32_t chunk_size;           //  4  file_size;
    char format[4];                //  4  wave_str[4];

    char sub_chunk1_ID[4];         //  4  fmt_str[4];
    uint32_t sub_chunk1_size;      //  4  pcm_bit_num;
    uint16_t audio_format;         //  2  pcm_encode;
    uint16_t num_channels;         //  2  sound_channel;
    uint32_t sample_rate;          //  4  pcm_sample_freq;
    uint32_t byte_rate;            //  4  byte_freq;
    uint16_t block_align;          //  2  block_align;
    uint16_t bits_per_sample;      //  2  sample_bits;

    char sub_chunk2_ID[4];         //  4  data_str[4];
    uint32_t sub_chunk2_size;      //  4  sound_size;
};                                 // 44  bytes TOTAL

Now let’s create a read_wav_file() function to read this struct. We can read this WAV header as shown below.

void read_wav_file(std::string fname)
{
    // Open the WAV file
    std::ifstream wavfile(fname, std::ios::binary);

    if(wavfile.is_open())
    {
        // Read the WAV header
        Twavheader wav;
        wavfile.read(reinterpret_cast<char*>(&wav), sizeof(Twavheader));

        // If the file is a valid WAV file
        if (std::string(wav.format, 4) != "WAVE" || std::string(wav.chunk_ID, 4) != "RIFF")
        {
            wavfile.close();
            std::cerr << "Not a WAVE or RIFF!" << std::endl;
            return;
        }

        // Properties of WAV File
        std::cout << "FileName:" << fname << std::endl;
        std::cout << "File size:" << wav.chunk_size+8 << std::endl;
        std::cout << "Resource Exchange File Mark:" << std::string(wav.chunk_ID, 4) << std::endl;
        std::cout << "Format:" << std::string(wav.format, 4) << std::endl;
        std::cout << "Channels: " << wav.num_channels << std::endl;
        std::cout << "Sample Rate: " << wav.sample_rate << " Hz" << std::endl;
        std::cout << "Bits Per Sample: " << wav.bits_per_sample << " bits" << std::endl;

        // Read wave data
        std::vector<int16_t> audio_data( wav.sub_chunk2_size / sizeof(int16_t) );
        wavfile.read(reinterpret_cast<char*>( audio_data.data() ), wav.sub_chunk2_size );
        wavfile.close();  // Close audio file

        // Display some audio samples
        const size_t numofsample = 20;
        std::cout <<"Listin first " << numofsample << " Samples:" << std::endl;
        for (size_t i = 0; i < numofsample && i < audio_data.size(); ++i)
        {
             std::cout << i << ":" << audio_data[i] << std::endl;
        }     

        std::cout << std::endl;
    }
}

finally, we can read and display like so:

read_wav_file("D:\\sample.wav");


Is there a full C++ example to read the WAV waveform audio file format in C++?

Here is the full C++ example to read a file which uses the WAV waveform audio file format.

#include <iostream>
#include <fstream>
#include <vector>
#include <cstdint>

// WAV file header structure
struct Twavheader
{
    char chunk_ID[4];              //  4  riff_mark[4];
    uint32_t chunk_size;           //  4  file_size;
    char format[4];                //  4  wave_str[4];

    char sub_chunk1_ID[4];         //  4  fmt_str[4];
    uint32_t sub_chunk1_size;      //  4  pcm_bit_num;
    uint16_t audio_format;         //  2  pcm_encode;
    uint16_t num_channels;         //  2  sound_channel;
    uint32_t sample_rate;          //  4  pcm_sample_freq;
    uint32_t byte_rate;            //  4  byte_freq;
    uint16_t block_align;          //  2  block_align;
    uint16_t bits_per_sample;      //  2  sample_bits;

    char sub_chunk2_ID[4];         //  4  data_str[4];
    uint32_t sub_chunk2_size;      //  4  sound_size;
};                                 // 44  bytes TOTAL

//------------------------------------------------------------------------------
void read_wav_file(std::string fname)
{
    // Open the WAV file
    std::ifstream wavfile(fname, std::ios::binary);

    if(wavfile.is_open())
    {
        // Read the WAV header
        Twavheader wav;
        wavfile.read(reinterpret_cast<char*>(&wav), sizeof(Twavheader));

        // If the file is a valid WAV file
        if (std::string(wav.format, 4) != "WAVE" || std::string(wav.chunk_ID, 4) != "RIFF")
        {
            wavfile.close();
            std::cerr << "Not a WAVE or RIFF!" << std::endl;
            return;
        }

        // Properties of WAV File
        std::cout << "FileName:" << fname << std::endl;
        std::cout << "File size:" << wav.chunk_size+8 << std::endl;
        std::cout << "Resource Exchange File Mark:" << std::string(wav.chunk_ID, 4) << std::endl;
        std::cout << "Format:" << std::string(wav.format, 4) << std::endl;
        std::cout << "Channels: " << wav.num_channels << std::endl;
        std::cout << "Sample Rate: " << wav.sample_rate << " Hz" << std::endl;
        std::cout << "Bits Per Sample: " << wav.bits_per_sample << " bits" << std::endl;

        // Read wave data
        std::vector<int16_t> audio_data( wav.sub_chunk2_size / sizeof(int16_t) );
        wavfile.read(reinterpret_cast<char*>( audio_data.data() ), wav.sub_chunk2_size );
        wavfile.close();  // Close audio file

        // Display some audio samples
        const size_t numofsample = 20;
        std::cout <<"Listing first " << numofsample << " Samples:" << std::endl;
        for (size_t i = 0; i < numofsample && i < audio_data.size(); ++i)
        {
             std::cout << i << ":" << audio_data[i] << std::endl;
        }     

        std::cout << std::endl;
    }
}
//------------------------------------------------------------------------------
int main()
{
    read_wav_file("D:\\sample.wav");

    system("pause");
    return 0;
}

The output will be as below.

FileName:D:\sample.wav
File size:563756
Resource Exchange File Mark:RIFF
Format:WAVE
Channels: 2
Sample Rate: 44100 Hz
Bits Per Sample: 16 bits
Listing first 20 Samples:
0:-1934
1:-1934
2:-1276
3:-1276
4:-241
5:-241
6:598
7:598
8:282
9:282
10:242
11:242
12:314
13:314
14:208
15:208
16:-128
17:-128
18:-1226
19:-1226

Note that this struct can be used in C applications too. As you see, in modern C++, we can easily read WAV wave files, now you can display or edit wave files.

Learn How To Read The WAV Waveform Audio File Format In C++. C++ Builder logo

C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.

There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise version.

The post Learn How To Read The WAV Waveform Audio File Format In C++ first appeared on Learn C++.]]>
5570
What Is Assignment Operator Overloading? https://learncplusplus.org/what-is-assignment-operator-overloading/ Wed, 22 May 2024 05:00:00 +0000 https://learncplusplus.org/?p=14904 One of the most commonly used features of C++ software, in common with many programming languages, is the “=” assignment operator. These take the form of copy assignment and move assignment operators. In C++, we can...

The post What Is Assignment Operator Overloading? first appeared on Learn C++.]]>
One of the most commonly used features of C++ software, in common with many programming languages, is the “=” assignment operator. These take the form of copy assignment and move assignment operators. In C++, we can overload the “=” assignment operator by creating a new assignment operator, this is called assignment operator overloading. In this post, we explain what an assignment operator is, what overloading means, and how we can overload an assignment operator in C++.

What is assignment operator?

In C++, the “=” operator is the assignment operator, it is used for assigning values between two data types, such as int, string, class objects, struct objects, etc. By default, it copies the right value into the left value. Assignment Operators are predefined to operate only on built-in Data types. Here is a simple example to use this assignment operator,

class Tuser
{
   public:
      std::string name;
}

main()
{
   Tuser user1, user2;
   user2 = user1;
}

In example above, “=” assignment operator will copy name of user1 to user2.

The Copy Assignment Operator, in a class, is a non-template non-static member function that is declared with the “operator=“. When you create a class or a type that is copy assignable (that you can copy with the = operator symbol), it must have a public copy assignment operator. If you are new to assignment operator, here we have more details for you:

Is there an example to default assignment operator?

Here is a simple usage of assignment operator (=),

int x1 = 10, x2;

x2 = x1;  // copy x1 value to x2

Now, let’s see what happens with the default assignment operator when we use between class objects. Let’s assume that we have a Tuser class that has a name string variable in private. We can add a constructor to set this private name variable. We can also add a print_name() method to print this private name. Our Tuser class will be as follows:

class Tuser
{
   private:
      std::string name;

   public:
      Tuser( std::string s) // constructor
      {
         name = s; // set private name from a given string
      }

      // method to print name
      void print_name()
      {
            std::cout << name << std::endl;
      }
}

Normally, when you create a datatype such as a class it has a default assignment operator. So, we can use it as shown below.

user2 = user1; // using assignment operator

Here is a full example about it,

#include <iostream>
#include <string>

class Tuser
{
   private:
      std::string name;

   public:
      Tuser( std::string s) // constructor
      {
         name = s; // set private name from a given string
      }

      // method to print name
      void print_name()
      {
            std::cout << name << std::endl;
      }
}

main()
{
    Tuser user1("Yilmaz");
    Tuser user2("Ata");

    user2 = user1; // using assignment operator

    std::cout << "Names after using assignment operator:" << std::endl;
    user1.print_name();
    user2.print_name();
}

This example above is also good to show how you can set and print a private variable in a class.

What is overload, overloaded, or overloading means in programming ?

In modern programming, overload, overloaded, overloading, function overloading, or method overloading terms are used for the name of the concept of having more than one method with the same name but with different parameters. In other words, it means that your code is providing a method or function with the same name, but with a different operation, maybe with different variable types.

Method or Function Overloading is used to operate with the same function by defining it with different variable types. By using Method or Function Overloading, a function can be used with the same name in different parameter types and multiple variations. If you want to discover more about it, here it is:

Then, what is assignment operator overloading?

Assignment operator overloading means we overload the “=” assignment operator by creating a new assignment operator. For example, if we want to use the assignment operator “=” to assign the value of the class members in a different way of copying them to another class member, then we should redefine a new assignment operator.  This is called assignment operator overloadingoverloading assignment operator, or overloaded assignment operator.

How can we use the assignment operator overloading?

For example, we can redefine the copy assignment operator in a class. If we go on from the example above, in our Tuser class we can overload this default assignment operator. Here is how we can do this:

// assignment operator overloading
    void operator=(const Tuser& U)
    {
        name = "Copy name of "+U.name;
    }

When we copy class objects, the new one will have “Copy name of ” prefix before the name.

Is there a full example about C++ assignment operator overloading?

Here is a full example of how to use C++ assignment operator overloading.

#include <iostream>
#include <string>

class Tuser
{
	private:
    std::string name;

	public:
    Tuser( std::string s) // constructor
    {
        name = s; // set private name from a given string
    }

    // assignment operator overloading
    void operator=(const Tuser& U)
    {
        name = "Copy name of "+U.name;
    }

    // method to print name
    void print_name()
    {
       std::cout << name << std::endl;
    }
};

int main()
{
    // Assigning by overloading constructor
    Tuser user1("Yilmaz");
    Tuser user2("Ata");

    std::cout << "Current Names:" << std::endl;
    user1.print_name();
    user2.print_name();

    // Using overloading assignment operator (=)
    user2 = user1;

    std::cout << std::endl<< "Names after using overloading assignment operator:" << std::endl;

    user1.print_name();
    user2.print_name();

    system("pause");
    return 0;
}

and the output will be:

Current Names:
Yilmaz
Ata

Names after using overloading assignment operator:
Yilmaz
Copy name of Yilmaz

As you see, in modern C++, we can easily overload the assignment operator.

What Is Assignment Operator Overloading? C++ Builder logo

C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.

There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise version.

The post What Is Assignment Operator Overloading? first appeared on Learn C++.]]>
14904