精华内容
下载资源
问答
  • 对象有几类成员
    千次阅读 多人点赞
    2018-08-25 13:01:33
      一个类的对象作为另一个类的数据成员。
     
         一个类中的数据成员除了可以是int, char, float等这些基本的数据类型外,还可以是某一个类的一个对象。用子对象创建新类。
     
         在C++中,当把一个类的对象作为新类的数据员时,则新类的定义格式可表示为:
     
    class X
     
    { 类名1  成员名1;
     
      类名2  成员名2;
     
      ……
     
      类名n  成员名n;
     
      ……//其它成员
     
    };
     
    (3)如果一个类A的对象作为另一个类B的数据成员,则在类B的对象创建过程中,调用其构造函数的过程中,数据成员(类A的对象)会自动调用类A的构造函数。
     
    但应注意:如果类A的构造函数为有参函数时,则在程序中必须在类B的构造函数的括号后面加一“:”和被调用的类A的构造函数,且调用类A的构造函数时的实参值必须来自类B的形参表中的形参。这种方法称为初始化表的方式调用构造函数。如:以上面定义的类X为例,在对类X的对象进行初始化时,必须首先初始化其中的子对象,即必须首先调用这些子对象的构造函数。因此,类X的构造函数的定义格式应为:
     
    X::X(参数表0):成员1(参数表1),成员2(参数表2),…,成员n(参数表n)
     
    { ……}
     
    其中,参数表1提供初始化成员1所需的参数,参数表2提供初始化成员2所需的参数,依此类推。并且这几个参数表的中的参数均来自参数表0,另外,初始化X的非对象成员所需的参数,也由参数表0提供。
     
    在构造新类的对象过程中,系统首先调用其子对象的构造函数,初始化子对象;然后才执行类X自己的构造函数,初始化类中的非对象成员。对于同一类中的不同子对象,系统按照它们在类中的说明顺序调用相应的构造函数进行初始化,而不是按照初始化表的顺序。












    以下定义了三个Student、Teacher和Tourpair,其中Student类的对象和Teacher类的对象作为了Tourpair的数据成员,观察对象的构造过程和构造函数被执行的顺序。
     

    include <iostream.h>

     
    class Student
     
    { public: 


       Student()
     
        { cout<<”construct student.\n”;
     
           semeshours=100;
     
           gpa=3.5;   }   


    protected:
     
         int semeshours;
     
         float gpa;
     
    };
     
    class Teacher
     
    { public:
     
         Teacher()
     
       { cout<<”construct Teacher.\n”; 


        }
     
     };
     
    class Tourpair
     
    {public:
     
         Tourpair()
     
         {cout<<”construct tourpair.\n”;
     
          nomeeting=0;  }
     
      protected:
     
          Student student;
     
          Teacher teacher;
     
          int nomeeting;
     
     };
     
    void main()
     
    {Tourpair tp;
     
    cout<<”back in main.\n”; }
     
    其执行结果是:
     
       construct student.
     
       construct teacher.
     
       construct tourpair.
     
       back in main.
     
          由此可见:主函数main()运行开始时,遇到要创建Tourpair类的对象,于是调用其构造函数Tourpair(),该构造启动时,首先分配对象空间(包含一个Student对
     
    象、一个Teacher对象和一个int型数据),然后根据其在类中声明的对象成员的次序依次调用其构造函数。即先调用Student()构造函数,后调用Teacher()构造函数,最后才执行它自己的构造函数的函数体。
     
         由于上例中Tourpair类的数据成员student和teacher的构造函数都是无参函数,所以系统在构造student和teacher对象时会自动调用各自的构造函数Student()和Teacher(),而不需要用初始化表的方式去调用。
     
    【例3-7】试分析以下程序的执行结果:
     

    include <iostream.h>

     

    include <string.h>

     
    class Student
     
    { public:
     
       Student(char *pName=”No name”)
     
          { cout<<”构造新同学:”<<pName<<endl;
     
             strncpy(name,pName,sizeof(name)); char * strncpy(char *dest, char *src, size_t n); 将字符串src中最多n个字符复制到字符数组dest中(它并不像strcpy一样遇到NULL才停止复制,而是等凑够n个字符才开始复制),返回指向dest的指针。              C语言中判断数据类型长度符
     
             name[sizeof(name)-1]=’\0’;  


            }
     
     Student(Student &s)
     
          { cout<<”构造copy of “<<s.name<<endl;
     
             strcpy(name, ” copy of “);  extern char *strcpy(char *dest,char *src);    把src所指由NULL结束的字符串复制到dest所指的数组中
     
             strcat(name,s.name);    extern char *strcat(char *dest,char *src);          把src所指字符串添加到dest结尾处(覆盖dest结尾处的’\0’)并添加’\0’。
     
             }
     
    ~Student()
     
     { cout<<”析构 “<<name<<endl; }
     
        protected:
     
        char name[40];  };
     
    class Tutor
     
    { public: 


           Tutor(Student &s):student(s)//此为初始化表,调用
     
                                                         //Student的拷贝构造函数
     
           { cout<<”构造指导教师 \n”;  }
     
       protected:
     
            Student student;
     
     };
     
    void main()
     
    {  Student st1;   //此处调用Student的构造函数Student(char  


               *pName=”No name”)
     
       Student st2(“zhang”); //同上
     
       Tutor tutor(st2); //此处调用Tutor的构造函数Tutor(Student &s)
     
       //在构造tutor对象的过程中,用初始化表调用
     
       //Student类的拷贝构造函数Student(Student &s)
     
    }
     
    执行结果如下:
     
    构造新同学:No name
     
    构造新同学:zhang
     
    构造copy of zhang
     
    构造指导教师
     
    析构  copy of zhang
     
    析构 zhang
     
    析构 No name
     
    3.2.7 利用初始化表对常量数据成员或引用成员提供初值
     
         如前所述,构造函数可对对象的数据成员进行初始化,但若数据成员为常量成员或引用成员时,就有所不同,如:
     
    class Sillyclass
     
    { public :
     
    Sillyclass()   // 此构造函数对成员ten和refi的初始化错误。
     
        { ten=10;
     
           refi=i; }
     
    protected:
     
        const int ten;   //常量数据成员ten
     
        int &refi;         //引用refi
     
    };
     
    说明:
     
    1. 造成以上错误的原因是在Sillyclass类的构造函数进入之后(开始执行其函数体时),对象结构已经建立,数据成员ten和refi已存在,而其数据成员ten为const,而refi为引用,所以在构造函数体内不能再对其指派新的值。
     
    2. 解决以上问题的方法是利用初始化表:在构造函数的括号后面加一“:”和初始化表,初始化表的格式是:
     
    数据成员名(值),如果有多个时,需要用逗号隔开。
     
    【例3-8】 类employee中包括私有数据成员x, 和2个公有函数成员example、show。程序中使用初始化表是x(215)。
     

    include <windows.h>

     

    include <iostream.h>

     
    // 定义类 employee
     
    class  employee
     
    {private:
     
         const int x;
     
      public:
     
         employee ();
     
         void show(); 


     };
     
    // employee的类外定义
     
    employee :: employee () : x (215)   // 初始化表
     
    {                   }
     
    // show()的定义。
     
    void employee :: show()
     
    {  cout << “\n    x的值是:”<< x << endl; }
     
    // 主函数
     
    void main()
     
    {   //生成对象并为x赋予初始值
     
       employee obj;
     
         //调用show显示x的值
     
       obj.show();
     
    }

    更多相关内容
  • C++中对象以及成员函数

    千次阅读 2017-11-17 16:57:23
    一个实体拥有自己的属性和行为,属性是私有的,行为是共有的,在C++中实体对应的就是对象,实体抽象数据类型就是,属性是成员变量,行为是成员函数。 面向对象思想的三大特征: 封装、继承、多态(静多态,动多态...

    一个实体拥有自己的属性和行为,属性是私有的,行为是共有的,在C++中实体对应的就是对象,实体抽象数据类型就是类,属性是成员变量,行为是成员函数。

    面向对象思想的三大特征:

    封装、继承、多态(静多态,动多态)

    访问限定符:

    public:任意位置都可以访问。

    protected:(继承和派生)一子类可以访问父类的保护成员。

    private:只有在类中才能被访问。

    如果在class类中没有说明是public还是private,则默认是private的。

    类和结构体都是自定义类型,那么他两之间有什么区别呢?

    在C++中,结构体默认是全部都可见的,而类中默认是私有的。

    C++的class和C语言的结构体的区别:

    ①struct Node是一个类型,在C语言中这样定义struct Node a;定义了一个结构体类型的a变量;在C++中,结构体定义对象可以写成Node a。

    ②空的结构体在C语言编译通不过,会报错;在C++中大小为1;不过在Linux环境里大小则为0;空的类(C++)大小也为1。

    这时就会有一个疑问??空类大小为何是1而不是0呢??

    空类的实例中不包含任何信息,本来求sizeof应该是0,但是当我们声明该类型的实例的时候,它必须在内存中占有一定的空间,否则无法使用这些实例。至于占多少内存,由编译器决定。VS中是1。

    我们定义一个类,里面都会实现一些函数,那么我们在进行函数设计的时候应该注意下面这问题:

    下面这两个函数有什么区别呢?

        void GetName(char *name);//1

        char *GetName();//2

    函数1引进了一个附本,修改的附本,并不会影响成员变量原本的值;

    函数2返回值是成员变量的指针,这样就有可能会修改私有成员变量的值。

    所以我们在进行函数设计的时候,应尽量避免返回成员变量的指针,修改到成员变量的值导致程序bug。

    成员函数我们可以将它们定义在类里,也可以定义在类外,一般建议定义在类外,在类里进行声明即可,这样会使代码看上去更美观,类里代码不会过多,看上去头重脚轻。定义在类外格式如下:

        void Student::Show();   //Student是类名,::是作用于分辨符,这个是一定要有的,Show()就是成员函数。

    那么类中定义和类外定义有什么区别呢??

    ①如果在类中定义,在函数调用的时候编译器会当做内联函数处理,在调用点将代码展开;

    ②如果在类外定义,在函数调用时和普通函数一样,进行栈桢的开辟和回退。

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

    系统会给我们提供一些函数,它们都有两个特点:公用的,内联的(无堆栈的开辟和清理)

    接下来我们主要讲一下几个成员函数:

    现在我们有一个CGoods类,私有成员变量有:物品名称(_name),数量(_amount),价格(_price)

    1、构造函数(初始化对对象的内存地址空间)

    构造函数和类名相同,构造函数可以重载。

    系统提供的默认构造函数:

    CGoods(){}

    自己提供的构造函数:

    CGoods(char *name,int amount,int price)

    {

             this->_name=newchar[strlen(name)+1];

             strcpy(_name,name);

             this->_amount=amount;

             this->_price=price;

    }

    this指针的类型是:CGoods *constthis,this指针的指向不能改变。

    实例化一个对象:

    ①分配对象内存空间

    ②调用对象的构造函数

    int main()

    {

             CGoodsgood1;//1

             CGoodsgood2("good2",20,10.5);//2

    }

    对象1会调用系统给出的默认构造函数,对象2会调用自己写的构造函数。

    没有实现的构造函数系统会给出默认的构造函数,如果有系统就不会调用默认构造函数,实例化一个不带参的对象不用加括号,比如对象1,带了括号就是函数的意思。

    2、析构函数(释放对象的内存空间所占的资源)

    析构函数不可以重载也不可以传参。调用的时机是在return 0;后在}前,先构造的对象后析构。

    系统提供的:

    ~CGood(){}

    自己实现的:

    ~CGoods()

    {

             delete[]_name;

             _name=NULL;

    }

    _name是动态开辟的所以需要销毁否则会造成内存泄漏。
    3、拷贝构造函数(用一个已经存在的对象初始化相同类型的新对象时,就会调用拷贝构造函数)

    系统提供的:

    CGoods(const CGoods &rhs)

    {

             this->_name=rhs._name;

             this->_amount=rhs._amount;

             this->_price=rhs._price;

    }

    int main()

    {

             CGoodsgood1;//1

             CGoodsgood2("good2",20,10.5);//2

             CGoodsgood3=goods2;

             ...

    }

    系统提供的是一个浅拷贝的函数,析构时就会出现问题:

    第三句代用拷贝构造函数,方式是浅拷贝。运行的话程序会崩掉,因为good2,good3同时指向一块内存,调用析构函数时,good3会先析构内存块就会被释放,good2就变成了野指针,析构时delete就会崩溃。


    先析构good3,内存块被释放,good2指向空,在此析构程序崩溃。

    自己写的拷贝构造:

    那么如果想要将下面这句构造成功,则需要:

    CGoods good3=good2;

    CGoods(const CGoods &rhs)

    {

             _name=newchar[strlen(rhs._name)+1];

             strcpy(_name,rhs._name);

             _amount=rhs._amount;

             _price=rhs._price;

    }

    调用的拷贝构造函数必须传引用,为了防止实参和形参递归调用。

    4、赋值运算符重载函数(用已存在的对象给另一个已存在的对象赋值)

    系统提供的:

    void operator=(const CGoods &rhs)

    {

             _name=rhs._name;

             _amount=rhs._amount;

             _price=rhs._price;

    }

    good3=good2;//good3已经定义过,进行重新赋值

    存在的问题:浅拷贝和内存泄漏。


    good3的指向变了之后指向了内存块1,析构时内存块1被释放,产生野指针再析构时会崩溃,内存块2没有被释放会产生内存泄漏。

    自己写的:

    void operator=(const CGoods &rhs)

    {

             if(this==&rhs)//防止自赋值

             {

                 return;

             }

             delete[]_name;//释放旧资源,防止内存泄漏

             _name=newchar[strlen(rhs._name)+1];//开辟新资源进行初始化

             strcpy(_name,rhs._name);

             _amount=rhs._amount;

             _price=rhs._price;

    }

    这样就不会出现浅拷贝和内存泄漏的问题。

     




    展开全文
  • C++中的对象成员

    千次阅读 2018-07-27 11:04:56
    譬如定义一个A,B,其中A为B的函数成员,此时,A为B的对象成员 程序的结果分析如下: 第一步:A pa(0,0),调用A的构造函数,长生第一行结果: AAAAAAAAAA 第二步:pa.printA();调用A的成员函数...

    参考网址:https://blog.csdn.net/rhzwan123/article/details/2105205

    譬如定义一个类A,类B,其中类A为类B的函数成员,此时,类A为类B的对象成员

    程序的结果分析如下:

    第一步:A pa(0,0),调用类A的构造函数,长生第一行结果:

    AAAAAAAAAA

    第二步:pa.printA();调用类A的成员函数,输出:

    A.x = 0  

    A.y =0

    第三步:B pa(45)  ,初始化数据成员时包含类A中的 A b,故而先调用A的构造函数,然后调用B的构造函数,输出结果为

    AAAAAAAAAA

    BBBBBBBBBB

    第四步: pb.printB()为类B中的成员函数,进入后先调用b.printA();而后输出B.a.输出结果为:

    A.x =99

    A.y =99

    B.a = 45

    第五步:类的周期完毕,调用析构函数,先调用B的析构函数,而后调用A的析构函数,输出结果为:

    B OVER!!

    99

    A OVER!!

    0

    A OVER!!

    举例:

    #include<iostream>
    using namespace std;
    class A
    {
    public:
    	A(int a,int b)
    	{x=a;y=b;cout<<"AAAAAAAAAA\n";}
    	void printA()
    	{cout<<"A.x="<<x<<endl<<"A.y="<<y<<"\n";}
    	~A()
    	{cout<<x<<"\nA OVER!!\n";}
    	private:
    		int x;
    		int y;
    	};
    
    class B
    {
    public:
    	B(int c) :b(99,99)
    	{ cout<<"BBBBBBBBBB\n";a=c;}
    	void printB()
    	{b.printA();cout<<"B.a="<<a<<"\n";}
    	~B(){cout<<"\nB OVER!!\n";}
    private:
    	int a;
    	A b;//对象成员
    };
    
    
    int main()
    {
    	A pa(0,0);
    	pa.printA();
    	B pb(45);
    	pb.printB();
    	return 0;
    }

    程序结果:

    展开全文
  • C++中派生对基类成员的访问形式主要以下两种: 1、内部访问:由派生中新增成员对基类继承来的成员的访问。 2、对象访问:在派生外部,通过派生对象对从基类继承来的成员的访问。 public继承 此时基类...

    类中的成员可以分为三种类型,分别为public成员、protected成员、public成员。
    类中可以直接访问自己类的public、protected、private成员,但类对象只能访问自己类的public成员。

    C++中派生类对基类成员的访问形式主要有以下两种:

    1、内部访问:由派生类中新增成员对基类继承来的成员的访问。
    2、对象访问:在派生类外部,通过派生类的对象对从基类继承来的成员的访问。

    public继承
    此时基类的public成员,protected成员,private成员对于派生类来说变为public成员,protected成员,private成员。
    protected继承
    此时基类的public成员,protected成员,private成员对于派生类来说变为protected成员,protected成员,private成员。

    private继承
    此时基类的public成员,protected成员,private成员对于派生类来说变为private成员,private成员,private成员。

    派生类及派生类对象对基类成员的访问权限如下:
    在这里插入图片描述

    展开全文
  • 最近写CPP的时候,需要类外部一个普通函数指针调用类成员函数。根据当初的设计,函数指针所指向的函数不需要传入一个类对象的引用的形参。为了保持最初的设计,在不创建对象的情况下考虑了种方案: 首先想到的是...
  • 不是由static修饰的是实例变量,也就是对象成员变量, 对象.变量名 调用 public class Variable { //定义变量 private static String name ;; //定义对象变量 private int age; public static void main...
  • C++类成员函数可以访问同类不同对象的私有成员

    千次阅读 多人点赞 2019-01-29 20:38:25
    因为 是成员函数,所以权限访问私有数据成员。如果是在main函数中直接,那肯定就会报错了,不能访问,因为这是在外不能访问私有数据成员。一个成员函数可以访问这个的私有数据成员,我们要理解这个对...
  • Java 成员有哪些?

    千次阅读 2019-05-29 10:13:35
    成员有5:属性、方法、构造器、代码块、内部 :具有相同属性(特征)和行为(动作)对象的集合,是抽象出来的。 属性:描述类型中的的特征(未完待续…) ...
  • 成员的访问权限_Java语言程

    千次阅读 2021-03-17 10:29:14
    成员的访问权限_Java语言程4.7.2 成员的访问权限Java将成员(成员变量和成员方法)的访问权限(可见性)划分为4种情况,按照访问权限的范围大小从小到大列出如下。·私有(private)成员:仅在本内中的...
  • C#第3讲:对象的主要成员

    千次阅读 多人点赞 2018-08-13 15:27:59
    c#是一个面向对象的语言,就是对现实世界某个事物的抽象,比如“人”他在程序中就可以用一个来表示,人年龄(Age),姓名(Name),人还可以吃饭(Eat)和睡觉(Sleep),根据这点我们就可以创建一个来...
  • C++类成员函数指针使用介绍

    万次阅读 多人点赞 2019-09-21 16:07:49
    在之前写过的博客中介绍过函数指针和指针函数的区别和简单用法(文章在这里),当时的Demo非常简单,都是C语言的写法,但是当在C++中直接像C那样使用类成员函数指针时就会报错:reference to non-static member ...
  • 中可以直接访问自己的public、protected、private成员,但类对象只能访问自己的public成员。 public继承 派生可以访问基类的public、protected成员,不可以访问基类的private成员; 派生类对象可以访问基类...
  • 构造时:基类构造函数→对象成员构造函数→派生本身的构造函数 析构时:派生本身的析构函数→对象成员析构函数→基类析构函数 写个小程序验证一下: #include <iostream> using namespace std; class ...
  • 获取Class类对象种方式

    千次阅读 2022-02-13 22:25:19
    反射、获取class对象
  • 一个只能一个对象,对么

    千次阅读 2021-03-17 10:56:20
    一个只能一个对象,不对。是用户定义的一种数据类型,可以使用这个类型来说明一个或多个变量,及对象是一种抽象的数据类型,是对对象的抽象;对象是对客观事物的抽象。一个只能一个对象,不对。是...
  • 1、在c++中,当把一个对象作为另一...2、如果一个A的对象作为另一个B的数据成员,则在B的对象创建过程中,调用其构造函数的过程中,数据成员A的对象)会自动调用A的构造函数。     但是应注...
  • 定义C++类对象的方法

    千次阅读 2021-06-08 09:56:45
    C++使用来定义对象也可以有几种方法。 (1) 先声明类型,然后再定义对象 例如: //定义student; class student //以class 开头 { public: //定义成员变量 char name[32]; //姓名 char add...
  • 友元/友元函数 通过指针访问内存地址 1.友元方法 #include<iostream> using namespace std; class A { public: A(){} ~A(){} friend class B; //声明友元 private: int num = 10; } class B { ...
  • Kotlin 中的伴生对象和静态成员

    千次阅读 多人点赞 2018-06-02 22:21:59
    在上面的例子中,我们知道了可以在 Java 代码中调用 Kotlin 中伴生对象成员,类似于 Java 中的静态成员。但是看上去和 Java 中的还是略区别,因为类名和方法名/属性setter,getter方法名之间多了个伴生对象的...
  • 首先我们定义一个Ctest,里面包含三个不同形式的成员函数,静态成员函数statFunc()、动态成员函数dynFunc()和虚拟函数virtFunc()。在main函数中我们利用cout标准输出流分别输出这三个函数的地址,程序如下所示:...
  • 【Java反射】类对象

    千次阅读 2021-06-17 15:04:24
    一个可以多个实例对象,但只能一个类对象。 2 获取类对象的三种方式 2.1 准备实体 People.java package study; public class People { private int id; private String name; public int getId() {
  • public class Student { String name; int age; public Student(String name,int age) { this.name=name; this.age=age; } } public class text { public static void ... Student[] a = ne
  • 在python中,可以通过class关键字定义,然后通过定义的来创建实例对象。语法格式如下: calss 类名: 体 注意事项 在python中使用class关键字来定义,定义时需要注意以下个事项: (1)代码块以...
  • C++中访问类成员变量的种方式

    千次阅读 2020-05-21 10:22:25
    //第一种,c++提供的类成员指针 int test::*p = &test::a; double test::*q = &test::b; string test::*m = &test::c; t.*p = 5; t.*q = 2.2; t.*m = "hello"; cout ;//5 cout ;//2.2 cout () ;//hello //第二种 t....
  • c++常对象和常成员函数详解

    千次阅读 2017-07-15 21:52:19
    对象对象是指该对象在其生命周期内,其所有的数据成员的值都不能被改变;定义对象时加上关键字const,该对象就是常对象,其一般形式如下:类名 const 对象名[(实参类别)]; 或者 const 类名 对象名[(实参类别)...
  • 派生内只可能访问基类的...派生类对象和基类对象只能访问自个的public成员 基类成员在继承后在派生中的权限:  基类权限: public private protected  继承权限:public 继承 public private
  • Java -- 成员内部不能含有static成员(汇总)

    千次阅读 多人点赞 2020-11-15 14:14:51
    文章目录1、为什么内部static成员时内部也必须声明为static2、JVM的加载规则 :3、成员内部中为什么不能静态方法和属性4、静态内部(public static class)和普通内部(public class)的区别5、Java中...
  • 【C++】C++对象、构造函数和析构函数

    千次阅读 多人点赞 2018-06-03 20:32:37
    它即可包含描述事物的数据,又可包含处理这些数据的函数,在程序运行时是被用作样板来建立对象的。所以要建立对象,首先必须定义。 定义 定义一个的一般格式为: class 类名{ private: 成员表1; public:...
  • 关于类成员函数中访问同类对象的私有成员,主要包含以下种场景: a. 在C++的类的成员函数中,允许直接访问该类的对象的私有成员变量。 b. 在类的成员函数中可以访问同类型实例的私有变量。 c. 拷

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 463,897
精华内容 185,558
热门标签
关键字:

对象有几类成员