C++ 类的相关知识 构造,析构,继承与多态

1,class

2,构造

3,析构

4,继承(extend)

-------------------------------------------------------------------------------------------------

#include <ios>

#include <iostream>
#include <string>
#include <stdio.h>
using std::string;

class person {
private:
  char * name;
  int age;
public:
  person();  //构造函数
  ~person();  //构造函数
  void set_name(const char * name); //成员函数
  void set_age(int age);
  const char * get_name();
  int get_age();
  void info();

};

-------------------------------------------------------------------------------------------------

#include"person.h"
person::person(){
 name="test";
 age=26;
 printf("construct person\n");
}
person::~person(){
  printf("deconstruct person\n");
}
  void person::set_name(const char * name){
    name=name;
  }
  void person::set_age(int age){
    age=age;
  }
  const char * person::get_name(){
    return name;
  }
  int person::get_age(){
    return age;
  }
  void person::info(){
    printf("%s, %d \n", name, age);
  }
-------------------------------------------------------------------------------------------------
#include"person.h"

 class student:public person{
 private:
 int id;
 public:
    student();
    ~student();
    void set_id(int id);
    int get_id();
    void info();
 };

-------------------------------------------------------------------------------------------------

#include "student.h"
    student::student(){
        id=1;
         printf("construct student\n");
    }
    student::~student(){
    printf("deconstruct student\n");
    }
    void student::set_id(int id){
    id=id;
    }
    int student::get_id(){
     return id;
    }
    void student::info(){
    printf("name:%s, age:%d, id:%d\n",get_name(), get_age(), id);
    }

-------------------------------------------------------------------------------------------------

#include <ios>
#include <iostream>
#include <string>
#include <stdio.h>
#include "person.h"
#include "student.h"
using namespace std;

int main()
{
    person p1 = person();
    p1.info();
    student s1 = student();
    s1.info();
    return 0;
}

-------------------------------------------------------------------------------------------------


5,多态(一种接口,多种方法)

多态的需求,植物大战僵尸,里边子弹的设计,每个子弹都继承parent_bull,这样僵尸受到各种子弹伤害时,直接调用指向父类的子类指针,实现伤害的计算。

设计一个父类,父类的的伤害函数为virtual 函数。

在子类中实现该虚函数。这样就可以直接用该子类的父类的指针,调用该子类的虚函数。



参考:

1,http://www.cnblogs.com/mr-wid/archive/2013/02/18/2916309.html

一、"" 的介绍
   C++, "" 来描述 "对象", 所谓的"对象"是指现实世界中的一切事物。那么类就可以看做是对相似事物的抽象, 找到这些不同事物间的共同点, 如自行车和摩托车, 首先他们都属于"对象", 并且具有一定得相同点, 和一些不同点, 相同点如他们都有质量、都有两个轮子, 都是属于交通工具等。"都有质量""两个轮子"属于这个对象的属性, "都能够当做交通工具"属于该对象具有的行为, 也称方法。
   
   类是属于用户自定义的数据类型, 并且该类型的数据具有一定的行为能力, 也就是类中说描述的方法。通常来说, 一个类的定义包含两部分的内容, 一是该类的属性, 另一部分是它所拥有的方法。以 "人类" 这个类来说, 每个人都有自己的姓名、年龄、出生日期、体重等, 人类的属性部分, 此外, 人能够吃饭、睡觉、行走、说话等属于人类所具有的行为。
   
   上面举例中所描述的 "" 类仅仅是具有人这种对象的最基础的一些属性和行为, 可以称之为人的"基类"再说说一些具有一些职业的人, 例如学生, 一个学生还具有"基类"中所没有的属性, 如学校、班级、学号; 也可以具有基类所不具有的行为, 如每天需要去上课, 需要考试等。
   
   学生类可以看做是基类的一个扩展, 因为他具有基类的所有属性和行为, 并且在此基础上增加了一些基类所没有的属性和行为, "学生"这样的类称为"人类"这个基类的"派生类"或者"子类"。在学生的基础上海可以进一步的扩展出其他更高级的类, "研究生"类。
    
   到此, 我们不再更深的去介绍类的其他相关知识。
       
二、C++类的定义
   C++中使用关键字 class 来定义类, 其基本形式如下:

    class 类名

    {

        public:

            //公共的行为或属性

 

        private:

            //公共的行为或属性

    };

 
   说明:
       . 类名需要遵循一般的命名规则;
       
       public  private 为属性/方法限制的关键字, private 表示该部分内容是私密的, 不能被外部所访问或调用, 只能被本类内部访问; public 表示公开的属性和方法, 外界可以直接访问或者调用。
           一般来说类的属性成员都应设置为private, public只留给那些被外界用来调用的函数接口, 但这并非是强制规定, 可以根据需要进行调整;
           
       . 结束部分的分号不能省略。
               
   类定义示例:
       定义一个点(Point), 具有以下属性和方法:
           ■ 属性: x坐标, y坐标
           ■ 方法: 1.设置x,y的坐标值; 2.输出坐标的信息。

       实现代码如下:

            class Point

            {

                public:

                    voidsetPoint(int x, int y);

                    voidprintPoint();

 

                private:

                    int xPos;

                    int yPos;

            };

           
   代码说明:
       上段代码中定义了一个名为 Point 的类, 具有两个私密属性, int型的xPosyPos, 分别用来表示x点和y点。在方法上setPoint 用来设置属性, 也就是 xPos yPos 的值printPoint 用来输出点的信息。
       
       类在定义时有以下几点需要注意:
           . 类的数据成员中不能使用 autoexternregister等进行修饰, 也不能在定义时进行初始化,  int xPos = 0; //;
           . 类定义时 private public 关键词出现的顺序和次数可以是任意的;
           . 结束时的分号不能省略, 切记!
           
           


           
三、C++类的实现
   在上面的定义示例中我们只是定义了这个类的一些属性和方法声明, 并没有去实现它, 类的实现就是完成其方法的过程。类的实现有两种方式, 一种是在类定义时完成对成员函数的定义, 另一种是在类定义的外部进行完成。
   
   1>. 在类定义时定义成员函数
       成员函数的实现可以在类定义时同时完成, 如代码:

 1         #include <iostream>

 2

 3         using namespace std;

 4

 5         class Point

 6         {

 7             public:

 8                 void setPoint(int x, int y) //实现setPoint函数

 9                 {

10                     xPos = x;

11                     yPos = y;

12                 }

13

14                 voidprintPoint()       //实现printPoint函数

15                 {

16                     cout<< "x = " << xPos << endl;

17                     cout<< "y = " << yPos << endl;

18                 }

19

20            private:

21                 int xPos;

22                 int yPos;

23        };

24

25        int main()

26        {

27            Point M;        //用定义好的类创建一个对象点M

28            M.setPoint(10, 20); //设置 M点 的x,y值

29            M.printPoint();     //输出 M点 的信息

30

31            return 0;

32        }

 
       运行输出:

        x = 10

        y = 20

 

        Process returned 0 (0x0)  execution time : 0.406 s

        Press any key to continue.

 
       与类的定义相比, 在类内实现成员函数不再是在类内进行声明, 而是直接将函数进行定义, 在类中定义成员函数时, 编译器默认会争取将其定义为 inline 型函数。
       
       
   2>. 在类外定义成员函数
       在类外定义成员函数通过在类内进行声明, 然后在类外通过作用域操作符 :: 进行实现, 形式如下:

        返回类型 类名::成员函数名(参数列表)

        {

            //函数体

        }

        
       将示例中的代码改用类外定义成员函数的代码:

 

 1         #include <iostream>

 2

 3         using namespace std;

 4

 5         class Point

 6         {

 7             public:

 8                 void setPoint(int x, int y); //在类内对成员函数进行声明

 9                 void printPoint();

10

11            private:

12                int xPos;

13                 int yPos;

14        };

15

16        void Point::setPoint(int x, int y) //通过作用域操作符 '::' 实现setPoint函数

17        {

18            xPos = x;

19            yPos = y;

20        }

21

22        void Point::printPoint()       //实现printPoint函数

23        {

24            cout<< "x = " << xPos << endl;

25            cout<< "y = " << yPos << endl;

26        }

27

28        int main()

29        {

30            Point M;        //用定义好的类创建一个对象点M

31            M.setPoint(10, 20); //设置 M点 的x,y值

32            M.printPoint();     //输出 M点 的信息

33

34            return 0;

35        }

        
        setPoint 成员函数来说, 在类内声明的形式为 void setPoint(int x, int y); 那么在类外对其定义时函数头就应该是 voidPoint::setPoint(int x, int y) 这种形式, 其返回类型、成员函数名、参数列表都要与类内声明的形式一致。
       
       

 


四、C++类的使用
   将一个类定义并实现后, 就可以用该类来创建对象了, 创建的过程如同 intchar 等基本数据类型声明一个变量一样简单, 例如我们有一个Point, 要创建一个Point的对象只需要:

        Point 对象名;


   创建一个类的对象称为该类的实例化, 在创建时我们还可以对对象的属性进行相关的初始化, 这样在创建完成后该对象就已经具有了一定得属性, 这种创建方式将在下一篇博文中进行学习。
   将类进行实例化后系统才会根据该对象的实际需要分配一定的存储空间。这样就可以使用该对象来访问或调用该对象所能提供的属性或方法了。
   
   还以上面的代码为例, 为了减少篇幅, 我们把 Point 类的实现放在 Point.h 头文件中, 这里不再贴出 Point 类的实现代码。
   

 1     #include <iostream>

 2     #include "Point.h"

 3

 4     using namespace std;

 5

 6     intmain()

 7     {

 8         Point M;        //用定义好的类创建一个对象 点M

 9         M.setPoint(10, 20);        //设置 M点 的x,y值

10        M.printPoint();             //输出 M点 的信息

11        cout<< M.xPos <<endl;      //尝试通过对象M访问属性xPos

12

13        return 0;

14     }

 
   代码在编译时会出现错误, 提示 error: 'int Point::xPos' isprivate, 这是 cout<< M.xPos <<endl; 这行造成的, 他试图访问一个 private 对象中的私密数据 xPos,如果将这行去掉便可正常运行。
   
   通过 对象名.公有函数名(参数列表); 的形式就可以调用该类对象所具有的方法, 通过 对象名.公有数据成员; 的形式可以访问对象中的数据成员。
   
   

 


五、对象的作用域、可见域与生存周期
   类对象的作用域、可见域以及生存周期与普通变量的保持相同, 当对象生存周期结束时对象被自动撤销, 所占用的内存被回收, 需要注意的是, 如果对象的成员函数中有使用 new 或者 malloc 申请的动态内存程序不会对其进行释放, 需要我们手动进行清理, 否则会造成内存泄露。
   

 


2,http://ticktick.blog.51cto.com/823160/194307/

 c++构造函数的知识在各种c++教材上已有介绍,不过初学者往往不太注意观察和总结其中各种构造函数的特点和用法,故在此我根据自己的c++编程经验总结了一下c++中各种构造函数的特点,并附上例子,希望对初学者有所帮助。

                                        c++类的构造函数详解                        

一、 构造函数是干什么的

class Counter
{

public:
          // 类Counter的构造函数
          // 特点:以类名作为函数名,无返回类型
         Counter()
         {
                m_value = 0;
         }
         
private:
      
          // 数据成员
          int m_value;
}


       该类对象被创建时,编译系统对象分配内存空间,并自动调用该构造函数->由构造函数完成成员的初始化工作

eg:    Counter c1;
        编译系统为对象c1的每个数据成员(m_value)分配内存空间,并调用构造函数Counter( )自动地初始化对象c1的m_value值设置为0

故:

        构造函数的作用:初始化对象的数据成员。


二、 构造函数的种类

class Complex 
{         

private :
         double    m_real;
         double    m_imag;

public:

         //    无参数构造函数
         // 如果创建一个类你没有写任何构造函数,则系统会自动生成默认的无参构造函数,函数为空,什么都不做
         // 只要你写了一个下面的某一种构造函数,系统就不会再自动生成这样一个默认的构造函数,如果希望有一个这样的无参构造函数,则需要自己显示地写出来
        Complex( void)
        {
             m_real = 0.0;
             m_imag = 0.0;
        } 
        
         //    一般构造函数(也称重载构造函数)
         // 一般构造函数可以有各种参数形式,一个类可以有多个一般构造函数,前提是参数的个数或者类型不同(基于c++的重载函数原理)
         // 例如:你还可以写一个 Complex( int num)的构造函数出来
         // 创建对象时根据传入的参数不同调用不同的构造函数
        Complex( double real,  double imag)
        {
             m_real = real;
             m_imag = imag;         
         }
        
         //    复制构造函数(也称为拷贝构造函数)
         //    复制构造函数参数为类对象本身的引用,用于根据一个已存在的对象复制出一个新的该类的对象,一般在函数中会将已存在对象的数据成员的值复制一份到新创建的对象中
         //    若没有显示的写复制构造函数,则系统会默认创建一个复制构造函数,但当类中有指针成员时,由系统默认创建该复制构造函数会存在风险,具体原因请查询 有关 “浅拷贝” 、“深拷贝”的文章论述
        Complex( const Complex & c)
        {
                 // 将对象c中的数据成员值复制过来
                m_real = c.m_real;
                m_img    = c.m_img;
        }            
    
         // 类型转换构造函数,根据一个指定的类型的对象创建一个本类的对象
         // 例如:下面将根据一个double类型的对象创建了一个Complex对象
        Complex::Complex( double r)
        {
                m_real = r;
                m_imag = 0.0;
        }

         // 等号运算符重载
         // 注意,这个类似复制构造函数,将=右边的本类对象的值复制给等号左边的对象,它不属于构造函数,等号左右两边的对象必须已经被创建
         // 若没有显示的写=运算符重载,则系统也会创建一个默认的=运算符重载,只做一些基本的拷贝工作
        Complex & operator=(  const Complex &rhs )
        {
                 // 首先检测等号右边的是否就是左边的对象本,若是本对象本身,则直接返回
                 if (  this == &rhs ) 
                {
                         return * this;
                }
                
                 // 复制等号右边的成员到左边的对象中
                 this->m_real = rhs.m_real;
                 this->m_imag = rhs.m_imag;
                
                // 把等号左边的对象再次传出
                // 目的是为了支持连等 eg:    a=b=c 系统首先运行 b=c
                // 然后运行 a= ( b=c的返回值,这里应该是复制c值后的b对象)    
                 return * this;
        }

};

下面使用上面定义的类对象来说明各个构造函数的用法:

void main()
{
         // 调用了无参构造函数,数据成员初值被赋为0.0
        Complex c1,c2;

         // 调用一般构造函数,数据成员初值被赋为指定值
        Complex c3(1.0,2.5);
         // 也可以使用下面的形式
        Complex c3 = Complex(1.0,2.5);
        
         //    把c3的数据成员的值赋值给c1
         //    由于c1已经事先被创建,故此处不会调用任何构造函数
         //    只会调用 = 号运算符重载函数
        c1 = c3;
        
         //    调用类型转换构造函数
         //    系统首先调用类型转换构造函数,将5.2创建为一个本类的临时对象,然后调用等号运算符重载,将该临时对象赋值给c1
        c2 = 5.2;
        
        // 调用拷贝构造函数( 有下面两种调用方式) 
        Complex c5(c2);
        Complex c4 = c2;   // 注意和 = 运算符重载区分,这里等号左边的对象不是事先已经创建,故需要调用拷贝构造函数,参数为c2

        
        
}

三、思考与测验

1. 仔细观察复制构造函数

        Complex( const Complex & c)
        {
                 // 将对象c中的数据成员值复制过来
                m_real = c.m_real;
                m_img = c.m_img;
        }    
        
为什么函数中可以直接访问对象c的私有成员?

2. 挑战题,了解引用与传值的区别

  Complex test1( const Complex& c)
  {
           return c;
  }
  
  Complex test2( const Complex c)
  {
          return c;
   }
   
   Complex test3()
   {
           static Complex c(1.0,5.0);
           return c;
   }
  
  Complex& test4()
  {
          static Complex c(1.0,5.0);
          return c;
  }
  
   void main()
  {
        Complex a,b;
    
         // 下面函数执行过程中各会调用几次构造函数,调用的是什么构造函数?
    
       test1(a);
       test2(a);
     
       b = test3();
       b = test4();
     
       test2(1.2);
        // 下面这条语句会出错吗?
       test1(1.2);      //test1( Complex(1.2 )) 呢?
  }
 
四、附录(浅拷贝与深拷贝)
 
       上面提到,如果没有自定义复制构造函数,则系统会创建默认的复制构造函数,但系统创建的默认复制构造函数只会执行“浅拷贝”,即将被拷贝对象的数据成员的值一一赋值给新创建的对象,若该类的数据成员中有指针成员,则会使得新的对象的指针所指向的地址与被拷贝对象的指针所指向的地址相同,delete该指针时则会导致两次重复delete而出错。下面是示例:
 
【浅拷贝与深拷贝】
 
#include <iostream.h>
#include < string.h>
class Person 
{
public :
        
         // 构造函数
        Person( char * pN)
        {
              cout <<  "一般构造函数被调用 !\n";
              m_pName =  new 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习是一种人工智能(AI)的子领域,致力于研究如何利用数据和算法让计算机系统具备学习能力,从而能够自动地完成特定任务或者改进自身性能。机器学习的核心思想是让计算机系统通过学习数据中的模式和规律来实现目标,而不需要显式地编程。 机器学习应用非常广泛,包括但不限于以下领域: 图像识别和计算机视觉: 机器学习在图像识别、目标检测、人脸识别、图像分割等方面有着广泛的应用。例如,通过深度学习技术,可以训练神经网络来识别图像中的对象、人脸或者场景,用于智能监控、自动驾驶、医学影像分析等领域。 自然语言处理: 机器学习在自然语言处理领域有着重要的应用,包括文本分、情感分析、机器翻译、语音识别等。例如,通过深度学习模型,可以训练神经网络来理解和生成自然语言,用于智能客服、智能助手、机器翻译等场景。 推荐系统: 推荐系统利用机器学习算法分析用户的行为和偏好,为用户推荐个性化的产品或服务。例如,电商网站可以利用机器学习算法分析用户的购买历史和浏览行为,向用户推荐感兴趣的商品。 预测和预测分析: 机器学习可以用于预测未来事件的发生概率或者趋势。例如,金融领域可以利用机器学习算法进行股票价格预测、信用评分、欺诈检测等。 医疗诊断和生物信息学: 机器学习在医疗诊断、药物研发、基因组学等领域有着重要的应用。例如,可以利用机器学习算法分析医学影像数据进行疾病诊断,或者利用机器学习算法分析基因数据进行疾病风险预测。 智能交通和物联网: 机器学习可以应用于智能交通系统、智能城市管理和物联网等领域。例如,可以利用机器学习算法分析交通数据优化交通流量,或者利用机器学习算法分析传感器数据监测设备状态。 以上仅是机器学习应用的一部分,随着机器学习技术的不断发展和应用场景的不断拓展,机器学习在各个领域都有着重要的应用价值,并且正在改变我们的生活和工作方式。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值