精华内容
下载资源
问答
  • 2017-03-30 15:21:54
    public class A{
    private static A a = new A(); //声明为static是为了确保只有一个对象存在,详见static修饰符
    private A(){} //构造方法为private,外部无法使用new来创建对象.
    public static A getA(){
    return a;
    }
    }
    main(){
    
     A b = new A();//错误做法,无法获取对象
    A b = A.getA();//正确做法
    }
    更多相关内容
  • 定义一个类只能创建一个对象

    千次阅读 2014-10-13 08:30:38
    有时我们的程序中需要定义一个类,这个类只能创建一个youxiaosh

           有时我们的程序中需要定义一个类,这个类只能创建一个有效实例,在很多公司的招聘笔试题中,也经常会遇到这样的题目。网上也有不少关于这个问题的帖子,但是都说的很笼统,或者帖子里面的程序多多少少有点错误。下面和大家分享一下我对于这个问题的认识,C++。

           建议使用第一种方法,可以自定义类对象限制个数。

           第一种方法,在类中创建一个静态变量Count,用来限制可创建的实例的数量。完整的程序片段如下,我尽量在程序中添加了所有的注释:

    #include <iostream>
    
    class SingleClass
    {
    public:
        static SingleClass* GetSingleClass()    //静态成员函数
        {
            if (Count > 0)
            //如果Count大于0,那么就调用new创建一个类指针,并且计数Count减1,否则返回NULL
            {
                Count--;
                return new SingleClass();
            }
            else
            {
                return NULL;
            }
        }
    private:
        SingleClass(){};
        static int Count;   //静态成员变量Count,不允许在类中初始化。定义为const则可以在这初始化,但是不可更改,不适合在这使用
    };
    
    int SingleClass::Count = 1; //Count的初始化,可以自己设置限制创建实例的个数
    
    int main()
    {
        SingleClass* test;  //只能通过定义类指针来创建类实例
        test = SingleClass::GetSingleClass();
        return 0;
    }

            上面程序第一次调用GetSingleClass函数时,可以得到一个正确的类对象指针。如果第二次调用GetSingleClass函数,则会得到NULL。static int Count变量不能在类中初始化,需要在类外初始化。
            第二种方法,在类中创建一个静态类指针变量pSinClass,初始化为NULL,当成功创建一个类实例时,pSinClass不再为NULL,若pSinClass不为NULL,则不能再创建类对象。完整的程序片段如下:

    #include <iostream>
    
    class SingleClass
    {
    public:
        static SingleClass* GetSingleClass()    //静态成员函数
        {
            if (pSinClass == NULL)
            //如果pSinClass为NULL,那么就调用new创建一个类指针,否则返回NULL
            {
                pSinClass = new SingleClass();
                return pSinClass;
            }
            else
            {
                return NULL;
            }
        }
    private:
        SingleClass(){};
        static SingleClass* pSinClass;   //静态成员变量pSinClass,不允许在类中初始化。定义为const则可以在这初始化,但是不可更改,不适合在这使用
    };
    
    SingleClass* SingleClass::pSinClass = NULL; //pSinClass的初始化
    
    int main()
    {
        SingleClass* test;  //只能通过定义类指针来创建类实例
        test = SingleClass::GetSingleClass();
        return 0;
    }

            上面介绍了两种简单的限制类实例个数的方法,个人见解,有不好的地方请谅解,有什么更好的建议,回复一下哈~~~

    展开全文
  • C++只能实例化一个对象

    千次阅读 2015-10-18 18:07:54
    # include # include using namespace std;1.创建class Student { public: static Student* Limit(); //静态成员函数 void display(); private: static Student *total; //静态数据成员指针
    # include <iostream>
    # include <string>
    using namespace std;

    1.创建类

    class Student
    {
    public:
        static Student* Limit();  //静态成员函数
        void display();
    private:
        static Student *total;    //静态数据成员指针
        Student(string ,int);
        string name;
        int age;
    };

    2.类外实现

    //初始化静态成员数据
    Student* Student::total = NULL;
    Student::Student(string nam = "0",int ag = 0)
    {
        name = nam;
        age = ag;
    }
    Student* Student::Limit()           //功能:只能通过此函数调用构造函数进行初始化,然后返回唯一对象地址
    {
    
                        //定义bool类型的b为了实现 total = new student();只运行一次, 
                        //大概过程:(要记住 "b是静态成员" )
                        // 1)主函数创建第一个对象
                        //   b = false(满足条件进入IF)-> b = true 执行创建对象语句->
                        //   return对象地址total
                        // 2)主函数创建第二个对象
                        //   b = true (不满足IF条件,不进入IF)不会创建新的对象,->return
                        //   对象地址total(total不变同变量b一个性质)
                        // 所以无论主函数怎样创建对象都是将第一次创建的对象的地址返回给主函数
    
       static bool b = false;   
        if (b == false)   
        {                               
            b = true;   
            total = new Student();   
        }   
        return total;
    }
    
    void Student::display()
    {
        cout<<"名字:"<<name<<"\n年龄:"<<age<<endl;
    }

    3.程序入口

    int main()
    {
        //Student m("ss",12);          //不可访问,构造函数为私有成员函数
        //m.display();
        Student* a = Student::Limit(); //只能通过调用公有的静态成员函数来创建对象,返回对象的存储地址
        a->display();
        Student* b = Student::Limit(); //不是创建新的对象而是将指针b指向原有对象(a指向的对象)
        b->display();
    }

    4.讲解
    根据上面这段代码,要想在程序中只许创建一个Student类对象,调用静态成员函数Limit()即可。
    例如:

    Student MyObj(“ss”,12); // 编译出错 - 因为构造函数是 private

    // 获得指向类对象指针的正确方法
    Student* pMyObj1 = Student::Limit();

    // 下面的语句不会创建新的类对象,它所创建的对象指针pMyObj2与上面创建的pMyObj1指针是一样的,
    // 也就是说pMyObj1和pMyObj2所指的对象是一样的

    Student* pMyObj2 = Student::Limit();

    /****************************************分割线(2015.10.19)*************************************/

    5.简化版(增强版)
    1.将类类型的指针是否为空作为判断条件
    2.解决销毁对象之后不能创建对象问题,设置析构函数将 total初始化为NULL;上面的那个程序对应将bool类型的值 true转为false ,false转为true
    3.解决拷贝构造函数创建对象的问题
    若主函数通过以下方式来实例化对象,会报错,拷贝构造函数为私有,不能访问

        Student c(*a);              /通过拷贝构造函数创建对象。这样会报错
        c.display();
    
    class Student
    {
    public:
        static Student* Limit(); 
        ~Student();             //   增加之处 
        void display();
    private:
        static Student *total;  
        Student(string ,int);
        Student(const Student &a());  // 3.增加之处
        string name;
        int age;
    };
    Student* Student::total = NULL;
    //   1.增加之处
    Student::~Student()
    {
        total = NULL;
    }
    Student::Student(string nam = "0",int ag = 0)
    {
        name = nam;
        age = ag;
    }
    Student* Student::Limit()   
        //    2.更改之处,改为用指针是否为空作为判断条件比上一个更好理解
        if (NULL == total)   
        {                               
            total = new Student();   
        }   
        return total;
    }
    
    void Student::display()
    {
        cout<<"名字:"<<name<<"\n年龄:"<<age<<endl;
    }

    PS:可以通过this指针来检验是否只能实例化一个对象

    void Student::display()
    {
        cout<<"名字:"<<name<<"\n年龄:"<<age<<endl;
        cout<<this<<endl;   //打印this指针
    }

    结果:

            名字:0
            年龄:0
            00419488
            名字:0
            年龄:0
            00419488

    主函数创建的“两个对象”存储地址是完全一致的,所以实质只实例化了一个对象

    展开全文
  • 静态建立一个类对象,是由编译器为对象在栈空间中分配内存,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个对象。使用这种方法,直接调用的构造函数; 动态建立类对象,是...

    在C++中,类的对象建立分为两种,一种是静态建立,如A a;另一种是动态建立,如A* ptr=new A;这两种方式是有区别的。

    1. 静态建立一个类对象,是由编译器为对象在栈空间中分配内存,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造函数;
    2. 动态建立类对象,是使用new运算符将对象建立在堆空间中。这个过程分为两步,第一步是执行operator new()函数,在堆空间中搜索合适的内存并进行分配;第二步是调用构造函数构造对象,初始化这片内存空间。这种方法,间接调用类的构造函数。
    那么如何限制类对象只能在堆或者栈上建立呢?下面分别进行讨论。

    只能在堆上创建对象

    类对象只能建立在堆上,就是不能静态建立类对象,即不能直接调用类的构造函数。
    方法一:
    容易想到将构造函数设为私有。在构造函数私有之后,无法在类外部调用构造函数来构造类对象,只能使用new运算符来建立对象。
    然而,new运算符的执行过程分为两步,C++提供new运算符的重载,其实是只允许重载operator new()函数,而operator()函数用于分配内存,无法提供构造功能。因此,这种方法不可以。

    方法二:
    当对象建立在栈上面时,是由编译器分配内存空间的,调用构造函数来构造栈对象。当对象使用完后,编译器会调用析构函数来释放栈对象所占的空间。编译器管理了对象的整个生命周期。
    我们试想,如果编译器无法调用类的析构函数,情况会是怎样的呢?

    比如,类的析构函数是私有的,编译器无法调用析构函数来释放内存。所以,编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性,其实不光是析构函数,只要是非静态的函数,编译器都会进行检查。如果类的析构函数是私有的,则编译器不会在栈空间上为类对象分配内存。

    因此,将析构函数设为私有,类对象就无法建立在栈上了。代码如下:

    class  A  
    {  
    public :  
        A(){}  
        void  destory(){ delete   this ;}  
    private :  
        ~A(){}  
    };  

    试着使用A a;来建立对象,编译报错,提示析构函数无法访问。这样就只能使用new操作符来建立对象,构造函数是公有的,可以直接调用。类中必须提供一个destory函数,来进行内存空间的释放。类对象使用完成后,必须调用destory函数。

    上述方法的缺点:
    1. 无法解决继承问题。如果A作为其它类的基类,则析构函数通常要设为virtual,然后在子类重写,以实现多态。因此析构函数不能设为private。还好C++提供了第三种访问控制,protected。将析构函数设为protected可以有效解决这个问题,类外无法访问protected成员,子类则可以访问。
    2. 另一个问题是,类的使用很不方便,使用new建立对象,却使用destory函数释放对象,而不是使用delete。(使用delete会报错,因为delete对象的指针,会调用对象的析构函数,而析构函数类外不可访问)这种使用方式比较怪异。

    方法三
    为了统一,可以将构造函数设为protected,然后提供一个public的static函数来完成构造,这样不使用new,而是使用一个函数来构造,使用一个函数来析构。代码如下,类似于单例模式:

    class  A  
    {  
    protected :  
        A(){}  
        ~A(){}  
    public :  
        static  A* create()  
        {  
            return   new  A();  
        }  
        void  destory()  
        {  
            delete   this ;  
        }  
    };  

    这样,调用create()函数在堆上创建类A对象,调用destory()函数释放内存。

    只在栈上生成对象

    只有使用new运算符,对象才会建立在堆上,因此,只要禁用new运算符就可以实现类对象只能建立在栈上。将operator new()设为私有即可。
    代码如下:

    class  A  
    {  
    private :  
        void * operator  new ( size_t  t){}      // 注意函数的第一个参数和返回值都是固定的   
        void  operator  delete ( void * ptr){}  // 重载了new就需要重载delete   
    public :  
        A(){}  
        ~A(){}  
    }; 

    只能创建一个对象?

    我们可以自定义类对象限制个数。
    方法一:在类中创建一个静态变量Count,用来限制可创建的实例的数量。

    include <iostream>
    class SingleClass
    {
    public:
        static SingleClass* GetSingleClass()    //静态成员函数
        {
            if (Count > 0)
            //如果Count大于0,那么就调用new创建一个类指针,并且计数Count减1,否则返回NULL
            {
                Count--;
                return new SingleClass();
            }
            else
            {
                return NULL;
            }
        }
    private:
        SingleClass(){};
        static int Count;   //静态成员变量Count,不允许在类中初始化。定义为const则可以在这初始化,但是不可更改,不适合在这使用
    };
    
    int SingleClass::Count = 1; //Count的初始化,可以自己设置限制创建实例的个数
    
    int main()
    {
        SingleClass* test;  //只能通过定义类指针来创建类实例
        test = SingleClass::GetSingleClass();
        return 0;
    }

    上面程序第一次调用GetSingleClass函数时,可以得到一个正确的类对象指针。如果第二次调用GetSingleClass函数,则会得到NULL。static int Count变量不能在类中初始化,需要在类外初始化。

    方法二
    在类中创建一个静态类指针变量pSinClass,初始化为NULL,当成功创建一个类实例时,pSinClass不再为NULL,若pSinClass不为NULL,则不能再创建类对象。
    程序如下:

    #include <iostream>
    class SingleClass
    {
    public:
        static SingleClass* GetSingleClass()    //静态成员函数
        {
            if (pSinClass == NULL)
            //如果pSinClass为NULL,那么就调用new创建一个类指针,否则返回NULL
            {
                pSinClass = new SingleClass();
                return pSinClass;
            }
            else
            {
                return NULL;
            }
        }
    private:
        SingleClass(){};
        static SingleClass* pSinClass;   //静态成员变量pSinClass,不允许在类中初始化。定义为const则可以在这初始化,但是不可更改,不适合在这使用
    };
    SingleClass* SingleClass::pSinClass = NULL; //pSinClass的初始化
    int main()
    {
        SingleClass* test;  //只能通过定义类指针来创建类实例
        test = SingleClass::GetSingleClass();
        return 0;
    }
    展开全文
  • 只能存在一个对象实例,只能提供一个取得其对象实例的方法,只能产生一个 对象 单例模式的实现需要   public class Single { //声明一个静态的私有的引用变量,指向一个有对象 private static Single only...
  • 设计一个只能创建一个唯一实例的——单例模式 1. 背景  老师布置了一个思考题:设计一个只能创建一个唯一实例的。让我们只要想一下思路即可。自己的第一反应就是设计模式中的单例模式。自己百度了一下单例...
  • 面向对象编程():对象 实训答案

    千次阅读 多人点赞 2021-03-22 17:24:06
    1、下列关于面向对象编程的说法,正确: A、只要使用Java语言解决问题,就是在使用面向对象编程思想解决问题。 B、对象是个体,从组具有相同属性和类似行为的个体中可以抽象,以后凡是要创建对象,只需要...
  • 单例(Singleton)一个类始终只能创建一个实例 构造器使用private修饰、;提供一个public方法作为该的访问点,该方法必须使用static修饰来作为成员;使用一个成员变量缓存已经创建的对象,该成员变量要被静态...
  • java中对象练习题

    千次阅读 2021-03-09 21:37:06
    对象一、选择题1、下面对方法的作用描述不正确的是:( d d )A、 使程序结构清晰 B、 功能复用 C、 代码简洁 D、 重复代码2、方法内定义的变量:( b b )A 、一定在方法内所有位置可见 B、 可能在方法内的局部位置...
  • 一个数组对象push进另一个数组

    千次阅读 2020-09-29 11:34:56
    小編今天在开发过程中遇到一个问题 这是一个三级联动,当我点击...我这样定义就固定了data里只能有一个对象,当返回多条的时候就会报错 正确代码:要定义一个新的数组,然后push进去就可以了,,, 你...
  • 设计一个简单的学生信息

    千次阅读 2020-10-26 12:32:27
    在面向对象软件中,也很多共享相同特征的不同的对象,可以利用这些对象的相同特征为它们建立一个集合,而这个集合就称为。 C++ 中是把各种不同类型的数据(称为数据成员)和对数据的操作(成员函数)组织在...
  • Python面向对象练习题汇总

    千次阅读 多人点赞 2020-07-29 17:34:32
    2. python中如何定义一个类的格式 class 类名(object): 成员(方法) 3. (class)由哪三个部分构成 类名,属性,方法。 4. 类名的命名规则是什么 要遵循标识符的命名规范,尽量使用大驼峰命名法,命名时做到“见名...
  • 下列有关的说法不正确的是 A对象一个实例 B任何一个对象只能属于一个具体的 C一个类只能有一个对象 D 对象的关系和数据类型与变量的关系相似 答案C 分析对象一个实例对象的关系和数据与变量...
  • C++学习笔记:()面向对象 & 对象

    千次阅读 多人点赞 2018-07-30 13:09:39
    目录 1.面向对象的概念 2.对象 2.1的定义格式 ...早期的计算机编程是基于面向过程的方法,例如实现算术运算1+1+2 = 4,通过设计一个算法就可以解决当时的问题。随着计算机技术的不断提高,计算机被用...
  • new一个对象的过程中发生了什么?

    千次阅读 2019-12-16 16:45:50
    java在new一个对象的时候,会先查看对象所属的类有没有被加载到内存,如果没有的话,就会先通过的全限定名来加载。加载并初始化完成后,再进行对象的创建工作。 我们先假设是第一次使用该,这样的话new一个...
  • 下列有关的说法不正确的是 A对象一个实例 B任何一个对象只能属于一个具体的 C一个类只能有一个对象 D 对象的关系和数据类型与变量的关系相似 答案C 分析对象一个实例对象的关系和数据与变量...
  • 如何使一个类只能实例化一个对象

    千次阅读 2009-11-08 22:43:00
    如何使一个类只能实例化一个对象时间:2008-05-17 05:19:08 来源:论坛整理 作者: 编辑:chinaitzhe如何让类只能被实例化一个对象,也就是只能实例一次呢?网友回复:Single模式..网友回复:class A { private: static ...
  • 对象总结

    千次阅读 多人点赞 2018-07-22 21:57:01
    我们都知道C语言是一个面向过程的语言,而C++是一门面向对象的语言。那么,到底什么是面向过程,什么又是面向对象呢? (为了简化博客长度,我们插一个关于这两个的区别的链接,这里不再赘述) ...
  • 1.同一内数据的共享 ...因此,如果我实例化一个对象,其对象本身是不能直接使用"."访问符访问其对象内的私有数据成员的,更不用说同一的其他实例化的对象了。 比如,我们有一个Student,其
  • 声明一个Dog,给Dog添加三个String类型的属性,分别是name,color,variety,定义两个方法,分别是,eat,run。 在main方法中创建一个名为wuhuarou的Dog对象,并设置name为五花肉,color为棕色,v...
  • 、赋值、引用 在python中赋值语句总是建立对象的引用值,而不是复制对象。因此,python变量更像是指针,而不是数据存储区域 这点和大多数语音类似吧,比如C++、Java等  1、先看例子: 1 2 3 ...
  • 在Java中一个类只能实现一个接口 C. 在Java中一个类不能同时继承一个类和实现一个接口 D. 在Java中接口只允许单一继承 2.下列不属于面向对象编程的三个特征的是 A.封装 B.指针操作 C.多态性 D.继承 3....
  • 1. 下列关于的构造函数和析构函数的叙述中,不正确的是________。A.的析构函数可以重载 B....一个类可以多个构造函数,但只能有一个析构函数。2. 下列说明中有关结构体定义的正确说法是_...
  • 怎样从一个DLL中导出一个C++

    千次阅读 2018-08-28 23:01:23
    怎样从一个DLL中导出一个C++ 自从Windows开始,动态链接库(DLL)就是Windows平台的一个组成部分。动态链接库允许在一个独立的模块中封装一系列的功能函数,然后以一个显式的C函数列表提供外部使用者使用。在上个...
  • 我们想调用这个普通方法之前,是不是得先new 一个对象,A a=new A() ;然后用对象调用a.normalFunc(); 那么为什么静态方法可以通过类名直接调用,实例方法不可以通过类名直接调用呢?事实上在加载的时候,的相关...
  • C++成员函数可以访问同类不同对象的私有成员

    千次阅读 多人点赞 2019-01-29 20:38:25
    example 如下例: class Test { public: Test(int v) : val(v) ...同一个类可以访问所有自己实例的私有成员, 数据成员是私有而不是实例私有, 成员是否可访问是的性质, 而不是对象的性质
  • 第三章 对象(课后习题)

    千次阅读 2018-04-24 12:30:56
    第三章课后习题、填空题(1)定义中关键字private、public和protected以后的成员的访问权限分别是 私有、 公有 和 保护。如果没有使用关键字,则所有成员默认定义为private权限。具有 public 访问权限的数据...
  • JVM的加载机制,规定一个类有且只有一个类加载器对它进行加载。而如何保证这个只有一个类加载器对它进行加载呢?则是由双亲委派模型来实现的。 一个类加载器收到了加载的请求,他不会去尝试加载这个,而是把这...
  •  派生对象只能访问基类的public成员。  protected(保护继承),private(私有继承)  派生中的成员可以访问基类的public成员和protected成员,但不能访问基类的private成员。  派生对象不能访问基类的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 615,300
精华内容 246,120
关键字:

一个类只能有一个对象是否正确

友情链接: pra9.zip