c ++类指针与类对象转化_C ++类和对象简介

c ++类指针与类对象转化

开始C ++类 ( Starting C++ Classes )

Hands typing on laptop
Sam Edwards / Getty Images
山姆·爱德华兹/盖蒂图片社

Objects are the biggest difference between C++ and C. One of the earliest names for C++ was C with Classes.

对象是C ++和C之间的最大区别。C ++的最早名称之一是带有类的C。

类和对象 ( Classes and Objects )

A class is a definition of an object. It's a type just like int. A class resembles a struct with just one difference: all struct members are public by default. All classes members are private.

类是对象的定义。 就像int一样。 类与结构类似,只是有一个区别:默认情况下,所有结构成员都是公共的。 所有班级成员都是私人的。

Remember—a class is a type, and an object of this class is just a variable.

请记住,一个类是一个类型,而这个类的一个对象只是一个变量

Before we can use an object, it must be created. The simplest definition of a class is:

必须先创建对象,然后才能使用它。 类的最简单定义是:

 class name {
 // members
 }

This example class below models a simple book. Using OOP lets you abstract the problem and think about it and not just arbitrary variables.

下面的示例类为一本简单的书建模。 使用OOP,您可以抽象问题并思考问题,而不仅仅是任意变量。

 // example one
 #include 
 #include 
 class Book
 {
 int PageCount;
 int CurrentPage; 
 public:
 Book( int Numpages) ; // Constructor
 ~Book(){} ; // Destructor
 void SetPage( int PageNumber) ;
 int GetCurrentPage( void ) ;
 }; 
 Book::Book( int NumPages) {
 PageCount = NumPages;
 }
 void Book::SetPage( int PageNumber) {
 CurrentPage=PageNumber;
 }
 int Book::GetCurrentPage( void ) {
 return CurrentPage;
 }
 int main() {
 Book ABook(128) ;
 ABook.SetPage( 56 ) ;
 std::cout << "Current Page " << ABook.GetCurrentPage() << std::endl;
 return 0;
 }

All the code from class book down to the int Book::GetCurrentPage(void) { function is part of the class. The main() function is there to make this a runnable application.

类书int Book :: GetCurrentPage(void){函数的所有代码都是该类的一部分。 main()函数可以使它成为可运行的应用程序。

了解书本课 ( Understanding the Book Class )

In the main() function a variable ABook of type Book is created with the value 128. As soon as execution reaches this point, the object ABook is constructed. On the next line the method ABook.SetPage() is called and the value 56 assigned to the object variable ABook.CurrentPage. Then cout outputs this value by calling the Abook.GetCurrentPage() method.

main()函数中,将创建一个Book类型的变量ABook,其值是128。一旦执行到这一点,就会构造对象ABook。 在下一行中,将调用方法ABook.SetPage() ,并将值56分配给对象变量ABook.CurrentPage 。 然后cout通过调用Abook.GetCurrentPage()方法输出此值。

When execution reaches the return 0; the ABook object is no longer needed by the application. The compiler generates a call to the destructor.

当执行到达返回值0时; 应用程序不再需要ABook对象。 编译器生成对析构函数的调用。

宣告课程 ( Declaring Classes )

Everything between Class Book and the } is the class declaration. This class has two private members, both of type int. These are private because the default access to class members is private.

Class Book}之间的所有内容都是类声明。 此类有两个私有成员,两个成员均为int类型。 这些是私有的,因为对类成员的默认访问是私有的。

The public: directive tells the compiler that accesses from here on is public. Without this, it would still be private and prevent the three lines in the main() function from accessing Abook members. Try commenting the public: line out and recompiling to see the ensuing compile errors.

public:指令告诉编译器从此处开始的访问是公共的。 没有这个,它将仍然是私有的,并阻止main()函数中的三行访问Abook成员。 尝试对公众发表评论整理并重新编译以查看随之而来的编译错误。

This line below declares a Constructor. This is the function called when the object is first created.

下面的这一行声明了一个构造函数。 这是在首次创建对象时调用的函数。

 Book( int Numpages) ; // Constructor 

It is called from the line

从线叫

 Book ABook(128) ; 

This creates an object called ABook of type Book and calls the Book() function with the parameter 128.

这将创建一个名为Book的ABook对象,并使用参数 128调用Book()函数。

有关图书类的更多信息 ( More About the Book Class )

In C++, the constructor always has the same name as the class. The constructor is called when the object is created and is where you should put your code to initialize the object.

在C ++中,构造函数始终与类具有相同的名称。 创建对象时将调用构造函数,并且应在其中放置代码以初始化对象。

In Book The next line after the constructor the destructor. This has the same name as the constructor but with a ~ (tilde) in front of it. During the destruction of an object, the destructor is called to tidy up the object and ensure that resources such as memory and file handle used by the object are released.

在书中构造函数后的下一行析构函数。 它的名称与构造函数相同,但前面带有〜(波浪号)。 在销毁对象期间,将调用析构函数来整理对象,并确保释放诸如对象所使用的内存和文件句柄之类的资源。

Remember—a class xyz has a constructor function xyz() and destructor function ~xyz(). Even if you don't declare, the compiler will silently add them.

请记住,类xyz具有构造函数xyz()和析构函数〜xyz()。 即使您不声明,编译器也会静默添加它们。

The destructor is always called when the object is terminated. In this example, the object is implicitly destroyed when it goes out of scope. To see this, modify the destructor declaration to this:

当对象终止时,析构函数总是被调用。 在此示例中,对象超出范围时将隐式销毁。 要看到这一点,请将析构函数声明修改为此:

 ~Book(){ std::cout << "Destructor called";} ; // Destructor 

This is an inline function with code in the declaration. Another way to inline is adding the word inline

这是一个内联函数,在声明中带有代码。 内联的另一种方法是添加内联一词

 inline ~Book() ; // Destructor

and add the destructor as a function like this.

并添加析构函数作为这样的函数。

 inline Book::~Book ( void ) { 
 std::cout << "Destructor called";
 }

Inline functions are hints to the compiler to generate more efficient code. They should only be used for small functions, but if used in appropriate places—such as inside loops—can make a considerable difference in performance.

内联函数是编译器生成更有效代码的提示。 它们仅应用于小型函数,但如果在适当的地方(例如内部循环 )使用,则可能会在性能上产生很大差异。

编写课堂方法 ( Writing Class Methods )

Best practice for objects is to make all data private and access it through functions known as accessor functions. SetPage() and GetCurrentPage() are the two functions used to access the object variable CurrentPage.

对象的最佳实践是将所有数据设为私有,并通过称为访问器功能的功能对其进行访问。 SetPage()GetCurrentPage()是用于访问对象变量CurrentPage的两个函数。

Change the class declaration to struct and recompile. It should still compile and run correctly. Now the two variables PageCount and CurrentPage are publicly accessible. Add this line after the Book ABook(128), and it will compile.

声明更改为struct并重新编译。 它仍应编译并正确运行。 现在,两个变量PageCountCurrentPage可公开访问。 在Book ABook(128)之后添加此行,它将进行编译。

 ABook.PageCount =9;

If you change struct back to class and recompile, that new line will no longer compile as PageCount is now private again.

如果将struct改回并重新编译,由于PageCount现在又是私有的,因此该新行将不再编译。

::符号 ( The :: Notation )

After the body of Book Class declaration, there are the four definitions of the member functions. Each is defined with the Book:: prefix to identify it as belonging to that class. :: is called the scope identifier. It identifies the function as being part of the class. This is obvious in the class declaration but not outside it.

在Book Class声明主体之后,有四个成员函数定义。 每个都用Book ::前缀定义,以将其标识为属于该类。 ::称为作用域标识符。 它标识该函数为该类的一部分。 这在类声明中很明显,但不在类声明之外。

If you have declared a member function in a class, you must provide the body of the function in this way. If you wanted the Book class to be used by other files then you might move the declaration of book into a separate header file, perhaps called book.h. Any other file could then include it with

如果您在类中声明了成员函数,则必须以这种方式提供函数的主体。 如果您希望Book类供其他文件使用,则可以将book声明移到一个单独的文件中,该文件可能称为book.h。 然后,其他任何文件都可以包含

 #include "book.h" 

继承与多态 ( Inheritance and Polymorphism )

This example will demonstrate inheritance. This is a two class application with one class derived from another.

此示例将演示继承。 这是一个两类应用程序,其中一个类是从另一个类派生的。

 #include 
 #include 
 class Point
 {
 int x,y;
 public:
 Point(int atx,int aty ) ; // Constructor
 inline virtual ~Point() ; // Destructor
 virtual void Draw() ;
 }; 
 class Circle : public Point {
 int radius;
 public:
 Circle(int atx,int aty,int theRadius) ;
 inline virtual ~Circle() ;
 virtual void Draw() ;
 };
 Point ::Point(int atx,int aty) {
 x = atx;
 y = aty;
 }
 inline Point::~Point ( void ) { 
 std::cout << "Point Destructor called";
 }
 void Point::Draw( void ) {
 std::cout << "Point::Draw point at " << x << " " << y << std::endl;
 }
 Circle::Circle(int atx,int aty,int theRadius) : Point(atx,aty) {
 radius = theRadius;
 }
 inline Circle::~Circle() {
 std::cout << "Circle Destructor called" << std::endl;
 }
 void Circle::Draw( void ) {
 Point::Draw() ;
 std::cout << "circle::Draw point " << " Radius "<< radius << std::endl;
 }
 int main() {
 Circle ACircle(10,10,5) ;
 ACircle.Draw() ;
 return 0;
 }

The example has two classes, Point and Circle, modeling a point and a circle. A Point has x and y coordinates. The Circle class is derived from the Point class and adds a radius. Both classes include a Draw() member function. To keep this example short the output is just text.

该示例有两个类,点和圆,对一个点和一个圆进行建模。 一个点具有x和y坐标。 Circle类是从Point类派生的,并添加了一个半径。 这两个类都包含一个Draw()成员函数。 为了使本示例简短,输出仅是文本。

遗产 ( Inheritance )

The class Circle is derived from the Point class. This is done in this line:

Circle类是从Point类派生的。 这是在以下行中完成的:

 class Circle : Point {

Because it is derived from a base class (Point), Circle inherits all the class members.

因为它是从基类(Point)派生的,所以Circle继承了所有类成员。

 Point(int atx,int aty ) ; // Constructor
 inline virtual ~Point() ; // Destructor
 virtual void Draw() ;
 Circle(int atx,int aty,int theRadius) ;
 inline virtual ~Circle() ;
 virtual void Draw() ;

Think of the Circle class as the Point class with an extra member (radius). It inherits the base class Member functions and private variables x and y.

将Circle类视为具有额外成员(半径)的Point类。 它继承了基类Member函数以及私有变量xy

It cannot assign or use these except implicitly because they are private, so it has to do it through the Circle constructor's Initializer list. This is something you should accept as is for now. I'll come back to initializer lists in a future tutorial.

它不能隐式分配或使用它们,因为它们是私有的,因此它必须通过Circle构造函数的Initializer列表进行操作。 这是您现在应该接受的东西。 我将在以后的教程中回到初始化列表。

In the Circle Constructor, before theRadius is assigned to the radius, the Point part of Circle is constructed through a call to Point's constructor in the initializer list. This list is everything between the: and the { below.

在Circle构造函数中,在将Radus分配给radius之前 ,通过调用初始化列表中Point的构造函数来构造Circle的Point部分。 此列表包含以下之间的所有内容::和{。

 Circle::Circle(int atx,int aty,int theRadius) : Point(atx,aty) 

Incidentally, constructor type initialization can be used for all built-in types.

顺便说一下,构造函数类型初始化可用于所有内置类型。

 int a1(10) ;
 int a2=10 ;

Both do the same.

两者都一样。

什么是多态? ( What Is Polymorphism? )

Polymorphism is a generic term that means "many shapes". In C++ the simplest form of Polymorphism is overloading of functions. For instance, several functions called SortArray( arraytype ) where sortarray might be an array of ints or doubles.

多态是一个通用术语,表示“许多形状”。 在C ++中,多态的最简单形式是函数的重载。 例如,几个称为SortArray(arraytype)的函数,其中sortarray可能是ints或double数组

We're only interested in the OOP form of polymorphism here, though. This is done by making a function (e.g. Draw() ) virtual in the base class Point and then overriding it in the derived class Circle.

不过,我们仅对OOP形式的多态感兴趣。 这是通过在基类Point中使一个函数(例如Draw()) 虚拟化 ,然后在派生类 Circle中重写它来完成的。

Although the function Draw() is virtual in the derived class Circle, this isn't actually needed—it's just a reminder to me that this it is virtual. If the function in a derived class matches a virtual function in the base class on name and parameter types, it is automatically virtual.

尽管函数Draw()在派生类Circle中是虚拟的,但实际上并不是必需的,这只是提醒我它是虚拟的。 如果派生类中的函数在名称和参数类型上与基类中的虚函数匹配,则它将自动为虚函数。

Drawing a point and drawing a circle are two very different operations with only the coordinates of the point and circle in common, so it's important that the correct Draw() is called. How the compiler manages to generate code that gets the right virtual function will be covered in a future tutorial.

画点和画圆是两个非常不同的操作,只有点和圆的坐标是相同的,因此调用正确的Draw()很重要。 以后的教程将介绍编译器如何管理生成具有正确虚拟功能的代码。

C ++构造函数 ( C++ Constructors )

建设者 ( Constructors )

A constructor is a function that initializes the members of an object. A constructor only knows how to build an object of its own class.

构造函数是一个初始化对象成员的函数。 构造函数只知道如何构建自己类的对象。

Constructors aren't automatically inherited between the base and derived classes. If you don't supply one in the derived class, a default will be provided but this may not do what you want.

构造函数不会在基类和派生类之间自动继承。 如果您没有在派生类中提供一个,则将提供默认值,但这可能无法满足您的要求。

If no constructor is supplied then a default one is created by the compiler without any parameters. There must always be a constructor, even if it is the default and empty. If you supply a constructor with parameters then a default will NOT be created.

如果没有提供构造函数,则编译器会创建一个默认的构造函数,不带任何参数。 即使它是默认值并且为空,也必须始终有一个构造函数。 如果为构造函数提供参数,则不会创建默认值。

Some points about constructors:

有关构造函数的一些要点

  • Constructors are just functions with the same name as the class.

    构造函数只是与类同名的函数。
  • Constructors are intended to initialize the members of the class when an instance of that class is created.

    构造函数旨在在创建该类的实例时初始化该类的成员。
  • Constructors are not called directly (except through initializer lists)

    构造函数不会直接调用(通过初始化列表除外)
  • Constructors are never virtual.

    构造函数从来都不是虚拟的。
  • Multiple constructors for the same class can be defined. They must have different parameters to distinguish them.

    可以定义同一类的多个构造函数。 它们必须具有不同的参数以区分它们。

There is a lot more to learn about constructors, for instance, default constructors, assignment, and copy constructors. These will be discussed in the next lesson.

关于构造函数,还有很多要学习的东西,例如,默认构造函数,赋值和复制构造函数。 这些将在下一课中讨论。

整理C ++析构函数 ( Tidying Up C++ Destructors )

A destructor is a class member function that has the same name as the constructor (and the class ) but with a ~ (tilde) in front.

析构函数是类成员函数,其名称与构造函数(和class)相同,但前面带有〜(波浪号)。

 ~Circle() ;

When an object goes out of scope or more rarely is explicitly destroyed, its destructor is called. For instance, if the object has dynamic variables such as pointers, then those need to be freed and the destructor is the appropriate place.

当对象超出范围或很少被显式销毁时,将调用其析构函数。 例如,如果对象具有动态变量(例如指针),则需要释放这些变量,并且析构函数是适当的位置。

Unlike constructors, destructors can and should be made virtual if you have derived classes. In the Point and Circle classes example, the destructor is not needed as there is no cleanup work to be done (it just serves as an example). Had there been dynamic member variables (like pointers) then those would have required freeing to prevent memory leaks.

与构造函数不同,如果您具有派生类,则可以并且应该将析构函数设为虚拟的。 在“ 圆”类示例中,不需要析构函数,因为没有要执行的清理工作(它只是一个示例)。 如果有动态成员变量(如指针 ),则需要释放这些成员变量以防止内存泄漏。

Also, when the derived class adds members that require tidying up, virtual destructors are needed. When virtual, the most derived class destructor is called first, then its immediate ancestor's destructor is called, and so on up to the base class.

同样,当派生类添加需要整理的成员时,需要虚拟析构函数。 如果是虚拟的,则首先调用派生程度最高的类的析构函数,然后调用其直接祖先的析构函数,依此类推直至基类。

In our example,

在我们的示例中

 ~Circle() ;
 then
 ~Point() ;

The base classes destructor is called last.

基类的析构函数称为last。

This completes this lesson. In the next lesson, learn about default constructors, copy constructors, and assignment.

这样就完成了本课程。 在下一课中,学习默认构造函数,复制构造函数和赋值。

翻译自: https://www.thoughtco.com/candand-classes-and-objects-958409

c ++类指针与类对象转化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值