C++ Copy Constructor Assignment Operator Difference Between Cold

Copy constructors sounds like a topic for an article from 1989. And yet, the changes in the new C++ standard affect the design of a class’ special member functions fundamentally. Find out more about the impact of move semantics on objects’ behavior and learn how to implement the move constructor and the move assignment operator in C++11.

C++11 is the informal name for ISO/IEC 14882:2011, the new C++ standard that was published in September 2011. It includes the TR1 libraries and a large number of new core features (a detailed discussion about these new C++11 features is available here; also see The Biggest Changes in C++11 (and Why You Should Care)):

  • Initializer lists
  • Uniform initialization notation
  • Lambda functions and expressions
  • Strongly-typed enumerations
  • Automatic type deduction in declarations
  • storage class
  • Control and query of object alignment
  • Static assertions
  • Type
  • Variadic templates

Important as these features may be, the defining feature of C++11 is rvalue references.

The Right Time for Rvalue References

Rvalue references are a new category of reference variables that can bind to rvalues.  Rvalues are slippery entities, such as temporaries and literal values; up until now, you haven’t been able to bind these safely to reference variables.

Technically, an rvalue is an unnamed value that exists only during the evaluation of an expression. For example, the following expression produces an rvalue:

x+(y*z); // A C++ expression that produces a temporary 

C++ creates a temporary (an rvalue) that stores the result of , and then adds it to . Conceptually, this rvalue evaporates by the time you reach the semicolon at the end of the full expression.

A declaration of an rvalue reference looks like this:

std::string&& rrstr; //C++11 rvalue reference variable

The traditional reference variables of C++ e.g.,

std::string& ref;

are now called lvalue references.

Rvalue references occur almost anywhere, even if you don’t use them directly in your code. They affect the semantics and lifetime of objects in C++11. To see how exactly, it’s time to talk about move semantics.

Get to Know Move Semantics

Hitherto, copying has been the only means for transferring a state from one object to another (an object’s state is the collective set of its non-static data members’ values). Formally, copying causes a target object to end up with the same state as the source , without modifying . For example, when you copy a string to , the result is two identical strings with the same state as .

And yet, in many real-world scenarios, you don’t copy objects but move them. When my landlord cashes my rent check, he moves money from my account into his. Similarly, removing the SIM card from your mobile phone and installing it in another mobile is a move operation, and so are cutting-and-pasting icons on your desktop, or borrowing a book from a library.

Notwithstanding the conceptual difference between copying and moving, there’s a practical difference too: Move operations tend to be faster than copying because they transfer an existing resource to a new destination, whereas copying requires the creation of a new resource from scratch. The efficiency of moving can be witnessed among the rest in functions that return objects by value. Consider:

string func()
string s;
//do something with s
return s;
string mystr=func();

When returns, C++ constructs a temporary copy of on the caller’s stack memory. Next, is destroyed and the temporary is used for copy-constructing . After that, the temporary itself is destroyed. Moving achieves the same effect without so many copies and destructor calls along the way.

Moving a string is almost free; it merely assigns the values of the source’s data members to the corresponding data members of the target. In contrast, copying a string requires the allocation of dynamic memory and copying the characters from the source.

Move Special Member Functions

C++11 introduces two new special member functions: the move constructor and the move assignment operator. They are an addition to the fabulous four you know so well:

  • Default constructor
  • Copy constructor
  • Copy assignment operator
  • Destructor

If a class doesn’t have any user-declared special member functions (save a default constructor), C++ declares its remaining five (or six) special member functions implicitly, including a move constructor and a move assignment operator. For example, the following class

class S{};

doesn’t have any user-declared special member functions. Therefore, C++ declares all of its six special member functions implicitly. Under certain conditions, implicitly declared special member functions become implicitly defined as well. The implicitly-defined move special member functions move their sub-objects and data members in a member-wise fashion. Thus, a move constructor invokes its sub-objects’ move constructors, recursively. Similarly, a move assignment operator invokes its sub-objects’ move assignment operators, recursively.

What happens to a moved-from object? The state of a moved-from object is unspecified. Therefore, always assume that a moved-from object no longer owns any resources, and that its state is similar to that of an empty (as if default-constructed) object. For example, if you move a string to , after the move operation the state of is identical to that of before the move, whereas is now an empty (though valid) string object.

Designing a Move Constructor

A move constructor looks like this:

C::C(C&& other); //C++11 move constructor

It doesn’t allocate new resources. Instead, it pilfers‘s resources and then sets to its default-constructed state.

Let’s look at a concrete example. Suppose you’re designing a class that represents a memory buffer:

class MemoryPage
size_t size;
char * buf;
explicit MemoryPage(int sz=512):
size(sz), buf(new char [size]) {}
~MemoryPage( delete[] buf;}
//typical C++03 copy ctor and assignment operator
MemoryPage(const MemoryPage&);
MemoryPage& operator=(const MemoryPage&);

A typical move constructor definition would look like this:

MemoryPage(MemoryPage&& other): size(0), buf(nullptr)
// pilfer other’s resource
// reset other

The move constructor is much faster than a copy constructor because it doesn’t allocate memory nor does it copy memory buffers.

Designing a Move Assignment Operator

A move assignment operator has the following signature:

C& C::operator=(C&& other);//C++11 move assignment operator

A move assignment operator is similar to a copy constructor except that before pilfering the source object, it releases any resources that its object may own. The move assignment operator performs four logical steps:

  • Release any resources that currently owns.
  • Pilfer ‘s resource.
  • Set to a default state.
  • Return .

Here’s a definition of ‘s move assignment operator:

MemoryPage& MemoryPage::operator=(MemoryPage&& other)
if (this!=&other)
// release the current object’s resources
delete[] buf;
// pilfer other’s resource
// reset other
return *this;

Overloading Functions

The overload resolution rules of C++11 were modified to support rvalue references. Standard Library functions such as now define two overloaded versions: one that takes for lvalue arguments as before, and a new one that takes a parameter of type for rvalue arguments. The following program populates a vector with objects using two () calls:

#include <vector>
using namespace std;
int main()
vector<MemoryPage> vm;

Both calls resolve as because their arguments are rvalues. moves the resources from the argument into ‘s internal objects using ‘s move constructor. In older versions of C++, the same program would generate copies of the argument since the copy constructor of would be called instead.

As I said earlier, is called when the argument is an lvalue:

#include <vector>
using namespace std;
int main()
vector<MemoryPage> vm;
MemoryPage mp1(1024);//lvalue
vm.push_back(mp); //push_back(const T&)

However, you can enforce the selection of even in this case by casting an lvalue to an rvalue reference using :

//calls push_back(T&&)


Alternatively, use the new standard function for the same purpose:

vm.push_back(std::move(mp));//calls push_back(T&&)

It may seem as if is always the best choice because it eliminates unnecessary copies. However, remember that empties its argument. If you want the argument to retain its state after a call, stick to copy semantics. Generally speaking, don’t rush to throw away the copy constructor and the copy assignment operator. In some cases, the same class could be used in a context that requires pure copy semantics, whereas in other contexts move semantics would be preferable.

In Conclusion

C++11 is a different and better C++. Its rvalue references and move-oriented Standard Library eliminate many unnecessary copy operations, thereby improving performance significantly, with minimal, if any, code changes. The move constructor and the move assignment operator are the vehicles of move operations. It takes a while to internalize the principles of move semantics – and to design classes accordingly. However, the benefits are substantial. I would dare predicting that other programming languages will soon find ways to usher-in move semantics too.

Danny Kalev is a certified system analyst by the Israeli Chamber of System Analysts and software engineer specializing in C++. Kalev has written several C++ textbooks and contributes C++ content regularly on various software developers’ sites. He was a member of the C++ standards committee and has a master’s degree in general linguistics.

See also:


The Assignment Operator Revisited
by Richard Gillam
Advisory Software Engineer, Text & International
IBM Center for Java Technology–Silicon Valley

If you think you know it all in the C++ world, it must mean you’re not talking to your colleagues very much. If I had any pretensions to knowing it all when I wrote my assignment-operator article ("The Anatomy of the Assignment Operator," C++ Report, Nov/Dec 1997), they didn’t last long afterwards.

The assignment-operator article drew a huge response, with a lot of people sending me corrections and disagreements of various kinds. The issues have been mounting up, so I thought maybe a follow-on article to discuss the issues would be appropriate.

The big mistake

One I heard about almost instantly from several people (and which I’m really glad I heard about before delivering a talk on this subject at C++ World) was a rather serious mistake. When I first did this article, I had the big "right answer" like this:

TFoo& TFoo::operator=(const TFoo& that) { if (this != &that) { TSuperFoo::operator=(that); TBar* bar1 = 0; TBar* bar2 = 0; try { bar1 = new TBar(*that.fBar1); bar2 = new TBar(*that.fBar2); } catch (...) { delete bar1; delete bar2; throw; } delete fBar1; fBar1 = bar1; delete fBar2; fBar2 = bar2; } return *this; }

This was wrong, and it was caught in the review process. The problem here is that if you’re trying to transactionize the assignment, so that either all of it happens or none of it happens, this breaks that. If an exception occurs trying to new up or , the part of the object won’t have changed, but the part will have. The call to can’t go at the top of the function.

As I said, this was caught during the review process. So when the article ran, this example looked like this:

TFoo& TFoo::operator=(const TFoo& that) { if (this != &that) { TBar* bar1 = 0; TBar* bar2 = 0; try { bar1 = new TBar(*that.fBar1); bar2 = new TBar(*that.fBar2); } catch (...) { delete bar1; delete bar2; throw; } TSuperFoo::operator=(that); delete fBar1; fBar1 = bar1; delete fBar2; fBar2 = bar2; } return *this; }

Unfortunately, that’s wrong too. The problem is we’re still hosed if ’s assignment operator can also throw an exception, which is a reasonable thing to expect. If we succeed in creating our objects, but fails to create whatever he needs to (presumably he’s also transactionized), the object will correctly be left untouched, but we’ll leak the new we created. So the right answer (he said sheepishly) is this:

TFoo& TFoo::operator=(const TFoo& that) { if (this != &that) { TBar* bar1 = 0; TBar* bar2 = 0; try { bar1 = new TBar(*that.fBar1); bar2 = new TBar(*that.fBar2); TSuperFoo::operator=(that); } catch (...) { delete bar1; delete bar2; throw; } delete fBar1; fBar1 = bar1; delete fBar2; fBar2 = bar2; } return *this; }

The call to has to go inside the try. Notice that it goes after we create the new . We want to make sure creating the s has succeeded before we call because might succeed, changing the object, and we only want to change the object if we can carry out the whole assignment operation.

One interesting consequence of this is that you can imagine a class with a fairly deep inheritance chain where every class up the chain has other objects it owns. You’d call an assignment operator low in the chain, it’d create the objects it needs, then it’d call its parent, which would create the objects it needs and call its parent, and so on up the chain. Eventually, all of the new objects would have been created and would be pointed to by temporary variables on the stack. Then, at the root level, the assignment would finally begin to be carried out, with objects being deleted and the object’s data members being changed as each function returned. So the allocations happen in one order and the assignments and deletions happen in reverse order, which feels kind of awkward at first glance, but it gets the job done. It also means that there has to be enough free memory to hold two instances of every subobject, but there really isn’t a safe way around allocating all the extra memory.

By the way, I’ve also had several people question my assumption that the delete operations won’t throw exceptions. Technically they’re right, but I’d strongly counsel against letting this happen. I think it’s wise to declare "Destructors will not throw exceptions, nor will they allow exceptions thrown by functions they call to propagate out of them" to be a program invariant. The reason for this is that destructors are called in the course of handling exceptions. If exception-handling code can throw more exceptions, it’s extremely difficult, if not downright impossible, for everyone to properly clean up after himself, and extremely difficult for the program to completely recover from the error condition and go on. Therefore, throwing or propagating exceptions from within destructors is not a good idea.

The magic three

In my previous article, I singled out C++’s "magic three" functions, the default constructor, copy constructor and default assignment operator and said that one should always define them. This has raised a few hackles.

First, several people correctly pointed out that the default constructor is only defined by the compiler when you don’t create any other constructors. This is indeed true; I left this fact out for simplicity. In retrospect, I shouldn’t have.

Several people took exception to my statement that every class should define the "magic three." They were disturbed by the suggestion that every object should have a default constructor. They’re right. There are probably more objects for which it isn’t appropriate to have a default constructor than there are for which it is. Oftentimes, you can’t initialize an object to a meaningful state without some data being supplied from outside, or you can only do it by adding special-case code just to support a default constructor you don’t really need.

Occasionally, you even have a default constructor forced on you. Taligent’s CommonPoint system did this: its serialization facilities required a default consructor to work right, one of the bigger architectural gaffes in that system, in my opinion (of course, now I’ll get angry letters from ex-Taligent people explaining why it had to be that way).

I think what I really meant to say in the original article didn’t come through strong enough: You should always declare the magic three functions. This way, you make an explicit statement that you are not accepting the default implementations of these functions. If a default constructor isn’t appropriate for your class, don’t write one just for the sake of writing one; declare it private and give it an empty implementation. But be sure you declare it. Same goes for the copy constructor and assignment operator.

A number of people also suggested an improvement to my original advice: "If you don’t want it, declare it private and give it an empty implementation." You actually don’t have to give an unwanted function an implementation at all. You can declare the function private and not define it. The declaration will suppress the compiler-generated version of the function, but not defining it saves you from having to supply dummy code that doesn’t actually do anything and will never get called. Furthermore, while declaring the function private will prevent outside classes from calling it, it won’t prevent the same class from calling it. If you don’t supply an implementation, the class will get a link error if it calls its own unwanted magic functions. This is somewhat nonintuitive to debug, but it’s better than having the compiler silently let the caller get away with calling a function nobody’s supposed to call.

I also had people take rather violent exception to my suggestion that one should always define the copy constructor and assignment operator, even when they really do what you want them to do. They pointed out that it’s a lot of wasted boilerplate code, which is ugly and a pain to maintain. Furthermore, it’s possible for the compiler to perform optimizations on the default functions that it might not be able (or willing) to perform on user-written code. Most importantly, if you add or delete members from the class, the default copy constructor and assignment operator pick up the changes automatically. If you define these functions yourself, you have to remember to maintain them when the class definition changes, or you’ll have compiler errors or runtime bugs.

This is all very true, but I’ll stand by my original advice just the same. Boilerplate copy constructors and assignment operators are ugly code and a hassle to maintain, but being in the habit of always writing the copy constructor and assignment operator also puts you in the habit of thinking about just what the correct copy behavior is for all the members of your class. If all the members are integers, this probably isn’t a big deal, but if they’re pointers, it’s a very big deal. Getting into the habit of accepting the defaults without taking the time to think about it can also lead to bugs down the road if you mistakenly accept the default when it doesn’t do the right thing.

And, of course, you have to rely on comments to explain that you know about the default and are failing to define these functions on purpose. I’m always a little uncomfortable with relying on documentation for things like that.

Virtual assignment

Finally, several people, including my own manager here at IBM, disputed my advice to make the assignment operator of a class non-virtual. Let’s take a closer look at this issue.

Consider the following simple example:

X* x; void setX(const X& newX) { x = &newX; }

This will work right, but only if is a monomorphic class. But let’s say is polymorphic. Pretend it has an inheritance hierarchy like this:

X / \ Y Z

That is…

class X { // ... } class Y : public X { // ... } class Z : public X { // ... }

Now, if either or points to an object of class or , we’ll slice. Only the members defined in will get copied. If is an instance of or , the members defined by or won’t get led in with new values. If is an instance of or , the members defined by or won’t get copied into . Bad news.

The problem here, of course, is that we’re calling ’s assignment operator even when isn’t an instance of . The obvious solution, therefore, would be to make ’s assignment operator virtual. Then the correct assignment operator would be called. If we do this, the assignment operators would look like this:

X& X::operator=(const X& that) { // copy X’s members... return *this; } X& Y::operator=(const X& that) { Y& y = dynamic_cast<Y&>(that); X::operator=(that); // copy Y’s members using y return *this; } X& Z::operator=(const X& that) { Z& z = dynamic_cast<Z&>(that); X::operator=(that); // copy Z’s members using z return *this; }

Now, if and are actually both instances of , ’s assignment operator will get called and everybody will work right. Big improvement, right?

Well, consider the situation where is a and is a . In this case, the will fail, throwing a exception. Now we have a problem.

The exception is good, in a way, because it traps the mismatched classes and causes an error, rather than just slicing silently. But now we have an error condition we have to handle.

Remember that after an assignment succeeds, the objects on either side of the are to be computationally equivalent. That is, all of their visible state and their behavior should be the same. This implies that they should be the same class. What you really want is for it to look like morphed from whatever class it was to the same class is. , , and ’s assignment operators can’t do this; there’s no way to morph an existing object from one class to another (well, there kind of is, but we’ll get to it later). Instead, has to deal with this:

void setX(const X& newX) { try { x = &newX; } catch (bad_cast&) { X* temp = newX.clone(); delete x; x = temp; } }

Remember ? This is the polymorphic copy constructor. If you need polymorphic copy on a group of related classes, you define a virtual function called and every class in the tree overrides it to call his own copy constructor. You can’t just call ’s copy constructor for the same reason you can’t just call ’s assignment operator.

Another alternative is that doesn’t handle this condition, but some other class up the inheritance chain will have to, probably by doing the same thing we’re doing here: deleting the old and creating a new one of the right class. (There might be other meaningful ways of handling the exception, but they’d be more application-specific.)

The other possibility is that nobody handles the exception. We could just declare "assignment operators shall always be called with like classes on either side of the equal sign" as a program invariant. In other words, we declare heterogeneous assignment to be a condition which Should Never Happen.

Violations of program invariants ("Should Never Happen" conditions) are programmer errors; they’re things you’re assuming you’ll never run into at runtime. An exception shouldn’t be thrown for a violated invariant; since you’re not expecting it to happen at runtime, you don’t want to waste time putting in lots of extra code to handle it; the program is just malformed. And if you throw an exception that nobody catches, this simply causes your program to terminate. Quietly. With no error messages.

If your program’s going to terminate, you want it to terminate loudly, proclaiming to the world that Something Went Wrong. The way you do this is with the macro. You pass to an expression you expect to always evaluate to . If it evaluates to , it prints an error message that usually contains the text of the offending expression and the line number of the assert, and then the program terminates. (You can also cause asserts to be compiled out in production versions of your program, which will cause them to fail silently instead.)

So then instead of the dynamic cast, you can do a static cast and precede it with an assert:

X& Y::operator=(const X& that) { assert(typeid(that) == typeid(*this)); Y& y = static_cast<Y&>(that); X::operator=(that); // copy Y’s members using y return *this; }

By the way, my original attempt at this was

assert(typeid(that) == typeid(Y));

You don’t want to do it this way, because then when calls , will choke because isn’t an instance of . You’re not concerned that "that" is some particular static type; you’re concerned that "this" and "that" are the same type, whatever that type is.

So anyway, using the assert is one way around the heterogeneous-assignment problem, and it has a lot to recommend it, in situations where you really know that this invariant can hold.

But let’s go back to the previous answer for a minute and assume we’re going to catch the exception and finagle the assignment in . To refresh our memory, now looks like this:

void setX(const X& newX) { try { x = &newX; } catch (bad_cast&) { X* temp = newX.clone(); delete x; x = temp; } }

Let’s consider our possibilities here, ignoring for a moment. If and are both instances of or both instances of , we’re cool. If is an instance of and is an instance of , we’re also cool. with throw a exception, and we’ll catch it, delete , and new up a fresh new to assign to .

But what if is an instance of and is an instance of ? In this case, we’ll end up in ’s assignment operator, and the dynamic cast will succeed. is a subclass of , so dynamically casting a reference to a to a reference to an is legal. Every is also an . But because we’re in X’s assignment operator, we’ll only copy over the members of that were defined in . It’s our old friend slicing again.

What we’d have to do to avoid this is manually check for like class in each assignment operator and throw the ourselves, rather than relying on to do it for us.

Instead, my original solution to this problem was to avoid using the assignment operator in the first place:

void setX(const X& newX) { X* temp = newX.clone(); delete x; x = temp; }

I still like this. It’s simple and clear, and it works correctly with no extra hassles even when and are instances of different classes. The other solution, with the try/catch blocks, has an advantage in situations where the cost of deleting and newing the destination object is large and relatively rare (the try costs nothing in most modern compilers, so you in effect fast-path the case of like classes, but an actual throw can be quite expensive, so you achieve this fast-path effect at the expense of the different-classes case).

If the fast-path option makes sense for your application, I’d suggest avoiding the exception and doing it yourself like this:

void setX(const X& newX) { if (typeid(*x) == typeid(newX)) x = newX; else { X* temp = newX.clone(); delete x; x = temp; } }

Now if you avoid using the assignment operator in situations where slicing may be a problem, we’re still left with the question of whether it makes more sense to make the assignment operator virtual or non-virtual. I’m tending now to come down on the side of making the assignment operator virtual with an assert to check for the different-classes condition (since there’s no way to handle that in the assignment operator itself and therefore the calling function already has to be aware of the possibility of polymorphism and handle it).

However, there’s another problem here. I remembered Taligent’s coding guidelines discouraging virtual assignment operators, so I went back to see why it recommended that. I wish I had done that before. It turns out Taligent’s guidelines weren’t hard and fast on the subject. Instead they point out that defining

virtual X& Y::operator=(const X& that);

won’t keep the compiler from defining

Y& Y::operator=(const Y& that);

In other words, an override of an inherited assignment operator doesn’t suppress the compiler-generated default assignment operator. You’d still have to do that manually by declaring it private and not giving it an implementation.

And actually, this won’t even work because C++’s overload resolution rules will cause the suppressed version to win in some types of call. For instance, consider a class like this:

class Y : public X { public: virtual X& operator=(const X& that); // other method definitions… private: Y& operator=(const Y& that); }

Now consider this code snippet:

Y someY(/*agruments*/); // do something with someY Y someOtherY(/*arguments*/); someY = someOtherY;

Since both and are instances of , the overload resolution rules will declare the nonvirtual version of to be the "winner," instead of the inherited virtual . Since the nonvirtual is private, you’ll get an access-violation error at compile time.

Instead, you’d have to define the default assignment operator to call the virtual one. In every class that inherits the virtual one. Of course, this means defining it non-virtual. To see why, imagine if in the above example had a subclass called . If ’s was virtual, would have to override it, then it would have to override ’s , and then it would have to replace its own default assignment operator. Cutting any corners here risks creating situations where the "winning" function, according to the overload-resolution rules, is a function that is not accessible or isn’t implemented. Clearly, this gets ridiculous quickly as the inheritance hierarchy gets deeper.

One side effect in either case is that you have to define an override of the virtual even when you don’t strictly need one; otherwise, the "default" one will hide the virtual one.

So there you go. A truly foolproof method of handling polymorphism in assignment operators involves declaring both a virtual and a non-virtual assignment operator in every class (except the root class of each inheritance hierarchy), with the non-virtual calling the virtual and the virtual asserting that both objects involved are the same class. Any time a calling function couldn’t guarantee the invariant would hold, it would have to avoid using the assignment operator and manually delete the object referenced by the target variable and new up a new one of the proper type.

Beautiful, huh?

Other ways of morphing

Before I wrap this up, one more thing: I alluded earlier to the idea that there are ways of making an object look like it’s morphed from one class to another. There are two ways to do this, neither of which is really all that much of a winner.

One option is not to change the class of the object on the left-hand side. It’s perfectly reasonable to define assignment operators that take different types on the left and right-hand side. The operator in this case performs some kind of meaningful conversion of the incoming data as part of the assignment process. The result isn’t really a copy, but it may produce completely appropriate results. This solution is definitely the right way to go for some classes in some applications, but it’s not a general solution. Be sure to consider whether it’s appropriate for your classes before going to all the trouble above.

The other option is to fake inheritance using containment. In this case, the objects on the left and right-hand sides of the equal sign are the same class, but they behave like members of different classes because they own objects of different classes. The simplest version of this idea is a smart pointer that knows about polymorphism for a certain group of classes and does the right thing. All you’re really doing here is encapsulating in this object’s assignment operator the delete/new code you’d otherwise have to put in client code, but hiding junk like this in a smart-pointer class is very often a useful and effective way to go. (This is the essence of the State pattern, by the way.)


I don’t know about you, but there’s something really scary to me about a language where copying state from one object to another is this complicated. By now, I suspect at least a dozen or two programmers have contributed something new to this discussion. If it takes this many programmers to write a simple assignment operator, think how complicated writing code that actually does something meaningful must be!

The devil truly is in the details, especially in C++ programming.

I’m sure there are still other issues, both with the original article and this one, that I’ve missed. I’ve learned a lot about this, and I’m interested in continuing to lean. Keep those cards and letters coming!

Copyright ©1998 SIGS Publications, Inc. Used by permission.

0 thoughts on “C++ Copy Constructor Assignment Operator Difference Between Cold”


Leave a Comment

Your email address will not be published. Required fields are marked *