Comparison between C ++ and C #: function (5) clone function, interface-Oriented Programming

Source: Internet
Author: User
Document directory
  • Why c ++ does not need to clone functions and C # Does
  • Shortest copy
  • Deep copy
  • Copy constructor in C #

We know that C ++ has the concept of a copy constructor, and C # actually has a copy constructor. However, we generally do not mention this, and it is basically not used in this way. C # common clone functions. their functions are similar. They all copy some values. but the copy constructor directly copies the value of another object when calling the constructor to instantiate a class, and the clone function copies the value of another object after the instantiation.

Why do we need to clone a function?

Clone, as its name implies, is to copy something. we sometimes need to use this function to copy the content of an object to another object of the same type. here is a simple example. there is such a C # class
Class Arwen
{
Public string name;
Public int age;
}

Arwen = new Arwen ();
Arwen. Name = "weiwen ";
Arwen. Age = 24;
Arwen anotherarwen = new Arwen (); // another object, anotherarwen, needs the value in the Arwen?

If it is very easy to do in C ++. directly Arwen anotherarwen = Arwen; // The system will copy the values in Arwen to you by default. however, in C #, writing like this is also acceptable. but the expression is totally different. in C #, all your custom objects are of reference type. in this way, you do not copy all values of another object, but just copy one address. you may think of a stupid way
Anotherarwen. Age = Arwen. Age;
Anotherarwen. Name = Arwen. Name;
This is really a solution. If there are few fields in a class, it can be simply processed. however, this is inconvenient if there are many fields in it. this requires the clone function. how can I stay.

 

Why c ++ does not need to clone functions and C # Does

You will find a very interesting reality. For Class Object processing, C # And C ++ are exactly the opposite. if you use an object to assign values to another object directly as above, or pass an object parameter to a function. for example, there is a class void fun (Arwen Wen) {} You call fun (Arwen ). in this case, copy all the values of Arwen and then upload them. if you do not want to pass the value, you must use another method. for example, use a pointer or reference.
C # transmits an object parameter to the function like above, for example, fun (Arwen ). in this case, it is not a value, but a reference. if you want to upload data, try another method. this is to use the clone function to clone

 

The idea of interface-oriented programming in clone Functions

How to use a clone function? You can copy all the functions, such as cloneme or copyme, but this is obviously a bad method. If there are multiple classes,
How do you know the name of the clone function in each class?

Therefore, we recommend that you inherit an icloneable interface if you want to implement cloning in the class. This interface contains a function declaration object clone (); so when you call the clone function in the class, you can call the clone () function. All classes accept this naming convention. so now you know the benefits of the interface. it defines a set of specifications for your convenience in the future.

An example of interface-Oriented Programming

For example, let's talk about the charm of Interface Programming. If we simulate all the things in the world and generate classes one by one. now we are talking about the economy and society. then we want to know the price and value of each type of things. why? The first thing that comes to mind is that each class provides a function and calculates its own price. But what is the function name? Random random fetch may be messy, so I came to the ivaluable interface, which contains the function declaration double getvalue ();
Therefore, all classes inherit this interface and use the getvalue function to calculate their own prices. of course, some things are priceless and cannot be computed. for example, if someone asks you how much your wife is worth, you will get angry. of course, this is not the case unless your wife is in a special industry. so we only let those valuable things inherit the ivaluable interface.

Interface ivaluable

{

Double getvalue ();

}

The car-like and house classes inherit this interface. If you design a software and enter the brand or house type of the car, the system will return the amount of money. You can write code like this.

Double money;

Ferrari car = new Ferrari (); // The Farad class is a class inherited from the car.

Money = car. getvalue ();
Chery QQ qqcar = new Chery QQ ();
Money = qqcar. getvalue ();

Villa House = new villa (); // a class villa is a class inherited from the house
Money = house. getvalue ();

 

We found that if there are too many types of vehicles, it is inconvenient for you to use them, so we thought of using polymorphism. So we came up with such a function. Of course, the premise is that the function getvalue In The Car class is declared as virtual.
Int getallcarsvalue (car)
{
Return car. getvalue ();
}
Car car;
Double money;
Car = new Ferrari ();
Money = getallcarsvalue (CAR );
Car = new Chery QQ ();
Money = getallcarsvalue (CAR );
It's nice to use it. but you may want to be more comfortable, if not only the car class, but also the house class, with polymorphism processing. instead, all classes are combined for multi-state processing. you immediately think that in the world of C # classes, all classes are inherited from objet. It seems that such polymorphism can be implemented with it, but the object does not provide you with the getvalue () function, we can also think about it. If an object defines some functions for countless classes, it will be a huge bully. and since it is the top father, it has to reflect the common characteristics of all classes. getvalue is not the common nature of all classes.

Why? The interface is needed. We know that the virtual function can implement polymorphism, but the interface can also implement polymorphism. So the code is written like this.
Double getallclassvalue (ivaluable IV)
{
Return IV. getvalue ();
}

Then, call
Ivaluable ivclass;
Double money;

Ivclass = new Ferrari ();
Money = getallclassvalue (ivclass );
Ivclass = new Chery QQ ();
Money = getallclassvalue (ivclass );
Ivclass = new villa ();
Money = getallclassvalue (ivclass );

Through the above example, you can find out the beauty of interface-oriented programming.
First, a set of specifications are defined. In this way, classes inherited from interfaces can get the same name for a function to implement the same function. This facilitates class users.
2. polymorphism can be used.

 

Clone function usage

Class Arwen: icloneable
{
Public int height;
Public int age;

Object clone ()
{
Return this. memberwiseclone (); // a function that inherits from the object
}
}

Arwen = new Arwen ();
Arwen. Height = 111;
Arwen. Age = 24;
Arwen anotherarwen = new Arwen ();
Anotherarwen = (Arwen) Arwen. Clone (); // The type conversion is required because the clone function returns the object type.

As in the above example, all copies are value types, but what if there is a reference type in the class?
Assume that there is another class Book
{
Public int number;
Object clone ()
{
Return this. memberwiseclone ();
}
}

Then the class Arwen becomes like this.
Class Arwen: icloneable
{
Public int height;
Public int age;
Public book;

Object clone ()
{
Return this. memberwiseclone ();
}
}

In this case, only one reference of the book is copied. This is not what we want. After copying, all values of the two objects are independent and there is no connection between them. Therefore, we need to use deep copy.

 

Deep copy

Class Arwen: icloneable
{
Public int height;
Public int age;
Public book;

Object clone ()
{
Arwen an = new Arwen ();
An. Height = This. height;
An. Age = This. Age;
An. Book = (book) This. Book. Clone ();
Return;
}
}

Therefore, if deep copy is required, the reference type in the class must also provide a copy function, and also a deep copy function. of course, if there is only a value type in the class, there is no difference between deep copy and shallow copy.
So it is troublesome if the reference type field in the class also has the reference type. then the recursion continues. in this case, all involved classes must provide deep copy functions to truly implement deep copy. but we know that when designing a class, it is impossible for each class to copy the entire function.
So we don't have to make a deep copy every time. Sometimes, when we make a deep copy, we don't really want to make the copied value truly independent. It's a real deep copy.

 

Copy constructor in C #

The above is about copying after instantiation. In fact, it can also be copied during instantiation.

Class Arwen
{
Public int age;

Public Arwen (Arwen)
{
This. Age = Arwen. Age;
}
Public class1 (){}

}

Arwen = new Arwen ();
Arwen. Age = 999;
Arwen an = new Arwen (Arwen); // copy the value in Arwen to. An. Age = 999;

Of course, we rarely use this method. In many cases, we still use clone functions.

 

C ++ member variables are pointer Problems

We know that C ++ does not need to use a clone function, because you directly use the equal sign assignment to copy the value by default. In fact, it is equivalent to calling the memberwiseclone () function by default in C #.

But what should I do when there is a reference type like C # That requires deep copy ?? That is, when the member variables of the C ++ class have pointers.
Class Arwen
{
Public:
Int * age;
};

 

Int num = 444;
Arwen;
Arwen. Age = & num;

Arwen an = Arwen; // Replace the value in Arwen. The value of age is actually a pointer.
Cout <* an. Age; // The result is 444.

* Arwen. Age = 888;
Cout <* an. Age; // result 888

Obviously, when the value in the object Arwen is changed, the object an is also changed. this is not what we need. what we need is that Arwen is completely independent from the data in an *. age is still 444. The case here is the same as that of C #'s reference type. when the reference type value of one object is changed, the reference type value of the other object also changes.
In addition, the problem encountered at this time is not only that the value of an changes, but also the issue of pointer suspension, which makes the program crash. For example

Class Arwen
{
Public:
Int * age;
};

Arwen;
Arwen. Age = new int (444 );

Arwen an = Arwen; // Replace the value in Arwen. The value of age is actually a pointer.
Cout <* an. Age; // The result is 444.

Delete Arwen. Age;
Cout <* an. Age; // The Memory pointed to by the pointer an. Age is released. The pointer is suspended.

 

What should I do? That's complicated to process. We need to use the replication constructor, and some other smart pointers. We haven't fully understood it yet. I have to study it first.

 

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.