精华内容
下载资源
问答
  • C++什么类不能被继承

    千次阅读 2020-08-17 21:55:52
    C++什么类不能被继承 什么类不能被继承,首先思考派生类继承基类将会发生什么默认操作?派生类在调用自身的构造函数之前需要先调用基类的构造函数。那么我们就让这个不想别人继承的类的构造函数也无法派生类构造...

    C++什么类不能被继承

    C++什么类不能被继承,首先思考派生类继承基类将会发生什么默认操作?派生类在调用自身的构造函数之前需要先调用基类的构造函数。那么我们就让这个不想被别人继承的类的构造函数无法被其派生类构造。现在主要有三种方式阻止类的构造函数被调用,一是,将自身的构造函数与析构函数放在private作用域内;二是,将自身作为一个已存在类的友元类。这两种方式都能阻止派生类的继承(因为自身无法构造函数),第三种,使用C++11新特性final。

    一、将自身的构造函数与析构函数放在private作用域

    当本文声明一个对象时,编译器将调用构造函数(如果有),而这个调用将通常是public的,假如构造函数是private呢,由于在class外部不允许访问private成员,所以将会导致编译出错。如何解决这个问题呢?
    我们可以使用class的static公有成员,因为它独立于class对象之外,不必产生对象也可以使用它们。假如在类的某个static函数中创建了该class的对象,并以引用或者指针的形式将其返回(这里不以对象返回,主要是构造函数是私有的,外部不能创建临时对象),使用new在堆上创建对象,这样可以手动的创建和销毁对象,而如果在栈上创建对象,则会在生命周期结束的时候释放掉对象出现不可预估的错误。

    class OnlyHeapClass {
    public:
      static OnlyHeapClass* GetInstance() {
    //创建一个OnlyHeapClass对象并返回其指针
      return (new OnlyHeapClass);
    }
    void Destroy();
    private:
      OnlyHeapClass() {};
      ~OnlyHeapClass() {};
    };
    
    void OnlyHeapClass::Destroy() {
      delete this;
    }
    

    二、将自身作为一个已存在类的友元类

    下面本文要说明不可被继承类的第二种方式。利用友元的特性:友元不能被继承。什么是友元不能被继承性呢?利用了虚继承的一个特征就是虚基类的构造函数由最终子类负责构造。

    class CFinalClassMixin {//从这个类中继承的类都不能再被继承
      friend class Cparent;
    private:
      CFinalClassMixin() {}
      ~CFinalClassMixin(){}
    };
    class Cparent: virtual public CFinalClassMixin, public CXXX {
    public:
      Cparent() {}
      ~Cparent(){}
    };
    class CChild : public Cparent {
    public:
      CChild() {};//编译错误
      ~CChild() {};//编译错误
    };
    

    PS:为什么用虚继承?如果不是虚继承,那么CChild直接调用Cparent的构造函数,这是成立的,而且CChild是不需要调用CFinalClassMixin的构造函数。若把它声明为虚继承,那么CChild就必须负责CFinalClassMixin构造函数的调用,这样又因为不能继承friend类,所以不能调用,造成了错误。
    这里又会出现一个新问题,如果有很多的类不能被继承,那么就需要不断的往CFinalClassMixin中加入友元类。我们可以改进使用模板

    template<class T>
    class CFinalClassMixin {//从这个类中继承的类都不能再被继承
    friend class T;
    private:
      CFinalClassMixin() {}
      ~CFinalClassMixin(){}
    };
    class Cparent: virtual public CFinalClassMixin<Cparent>, public CXXX {
    public:
      Cparent() {}
      ~Cparent(){}
    };
    

    三、C++11的新特性

    直接使用类似JAVA的final的关键字final。

    class FinalClass final {
    
    };
    
    展开全文
  • c++之哪些成员函数不能被继承

    千次阅读 2020-06-14 21:25:50
    C++中,并不是所有的成员函数都能被子类继承,有三成员函数不能被子类继承,分别是:构造函数(包括拷贝构造)、析构函数、赋值运算符重载函数。 一,构造函数  构造方法用来初始化的对象,与父类的其它成员...

    C++中,并不是所有的成员函数都能被子类继承,有三类成员函数不能被子类继承,分别是:构造函数(包括拷贝构造)、析构函数、赋值运算符重载函数。

    一,构造函数   

    构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法)。因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要调用其父类的构造方法。   如果没有显式的构造函数,编译器会给一个默认的构造函数,并且该默认的构造函数仅仅在没有显式地声明构造函数情况下创建。 构造原则如下:

    1. 如果子类没有定义构造方法,则调用父类的无参数的构造方法。

    2. 如果子类定义了构造方法,不论是无参数还是带参数,在创建子类的对象的时候,首先执行父类无参数的构造方法,然后执行自己的构造方法。

    3. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数,则会调用父类的默认无参构造函数。

    4. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数且父类自己提供了无参构造函数,则会调用父类自己的无参构造函数。

    5. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数且父类只定义了自己的有参构造函数,则会出错(如果父类只有有参数的构造方法,则子类必须显示调用此带参构造方法)。

    6. 如果子类调用父类带参数的构造方法,需要用初始化父类成员对象的方式 。

    构造函数不能为虚:

    虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数

    要成为虚函数必须满足两点,一就是这个函数依赖于对象调用,因为虚函数就是依赖于对象调用,因为虚函数是存在于虚函数表中,有一个虚函数指针指向这个虚表,所以要调用虚函数,必须通过虚函数指针,而虚函数指针是存在于对象中的。二就是这个函数必须可以取地址,因为我们的虚函数表中存放的是虚函数函数入口地址,如果函数不能寻址,就不能成为虚函数。构造函数内联函数不可作为虚函数。

    二,析构函数   

    析构函数也不会被子类继承,只是在子类的析构函数中会调用父类的析构函数。

    • 如果没有将基类的析构函数定义为虚函数
      当基类指针指向子类对象时,如果基类的析构函数不是virtual,那么子类的析构函数将不会被调用,子类的资源没有正确是释放,因此造成内存泄露

    三,赋值运算符重载函数   

    赋值运算符重载函数也不会被子类继承,只是在子类的赋值运算符重载函数中会调用父类的赋值运算符重载函数。

    展开全文
  • C++中如何定义不能被继承

    千次阅读 2017-06-05 22:47:09
    学习过Java和c#的童鞋应该都知道,在Java中定义了关键字final表示一个类不能被继承,在C#中也有相同意义的关键字sealed表示一个类不能被继承,那仫在C++中呢?是没有这样特殊的关键字了,只能自己实现了。 如何在...

    学习过Java和c#的童鞋应该都知道,在Java中定义了关键字final表示一个类不能被继承,在C#中也有相同意义的关键字sealed表示一个类不能被继承,那仫在C++中呢?在C++11之前是没有的类似这样的关键字的,只能自己实现了。(在C++11中该关键字已经被加入到C++中,这个关键字的作用就是阻止类的进一步派生和虚函数的进一步重载)。
    如何在C++中定义一个不能被继承的类呢?
    想法一:私有构造函数来解决
    我们都知道在C++中子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动调用父类的析构函数。如果想要一个类无法被继承,那仫这个类的构造函数和析构函数必须是私有的,但是这样又会出现新的问题?就是这个类的构造函数和析构函数是私有的,我们如何获取和删除这个类的实例化对象呢?共有的静态函数就可以解决这个问题。

    class Base
    {
    public:
        //编写静态函数来创建和释放类的实例化
        static Base *GetSpace()
        {
            cout<<"GetSpace()"<<endl;
            return new Base();
        }
        static void DeleteSpace(Base *del)
        {
            cout<<"DeleteSpace()"<<endl;
            delete del;
        }
    private:
        //私有化构造和析构函数
        Base()
        {}
        ~Base()
        {}
    };
    
    int main()
    {
        //静态成员函数没有隐含this指针参数,使用类型::作用域访问符直接调用静态成员函数
        Base *b=Base::GetSpace();
        Base::DeleteSpace(b);
        system("pause");
        return 0;
    }

    私有构造函数和静态成员函数实现不能被继承的类
    这样的实现会不会存在什仫问题呢?通过观察上面的代码我发现实例化一个对象只能使用new来实例,也就是说这个新创建的对象只能在堆上生成,这就存在一定的局限性。那仫如何解决呢?
    想法二:利用虚拟继承的方法
    同样是将父类的构造函数私有化,但是却定义了一个模板类型的友元,因为友元的特性:如果一个类是另一个类的友元,友元类的每个成员函数都是另一个类的友元函数,都可访问另一个类中的保护或私有数据成员。我们在子类中调用父类的构造和析构函数是不会出错的。
    这种想法比方法一的想法好的一点就是:既可以在堆上实例化对象也可以在栈上实例化对象。

    template<typename T>
    class Base
    {
        friend T;  //定义友元,子类可以访问父类的私有成员对象
    private:
        Base()
        {
            cout<<"Base()"<<endl;
        }
        ~Base()
        {
            cout<<"~Base()"<<endl;
        }
    };
    //虚继承
    class Sub:virtual public Base<Sub>  
    {
    public:
        Sub()
        {
            cout<<"Sub()"<<endl;
        }
        ~Sub()
        {
            cout<<"~Sub()"<<endl;
        }
    };
    
    int main()
    {
        Sub s1;   //可以在栈上开辟
        Sub *s2=new Sub; //可以在堆上开辟
        delete s2;
        system("pause");
        return 0;
    }

    虚拟继承
    如果此时对Sub进行继承并对继承Sub的类进行实例化的时候是无法编译通过的。因为Sub是虚拟继承,所以当调用Test的构造函数的时候,会跳过Sub而直接调用Base的构造函数,又因为Base的构造函数是私有的且Test并不是Base的友元所以是不能调用的。
    所以Sub就是满足题意的不能被继承的类。

    class Test:public Sub
    {
    public:
        Test()
        {
            cout<<"Test()"<<endl;
        }
        ~Test()
        {
            cout<<"~Test()"<<endl;
        }
    };

    当然了在C++中定义不能被继承的类有许多其他的方法,在这里我就只介绍这两种啦!!!

    展开全文
  • 有时候我们并希望自己写的类被继承,怎么做呢? 方法很简单,只需要在定义时加上 sealed 关键字,用 sealed 关键字声明的也叫密封

    有时候我们并不希望自己写的类被继承,怎么做呢?

    方法很简单,只需要在定义类时加上 sealed 关键字,用 sealed 关键字声明的类也叫密封类,如下代码

        public sealed class Room
        {
            
        }
    

    强制派生会有什么错误呢?如下截图
    在这里插入图片描述
    Room 被定义为密封类,因此现在已经无法从 Room 类派生。

    如果只是想阻止基类中的虚成员被覆写,并不打算阻止整个类被继承,其实方法与密封类相同,在定义虚成员时加上 sealed 关键字即可,如下代码所示

        public class Car
         {
             protected virtual void Run()
             {
                 
             }
         }
        
        public class MyCar : Car
        {
            protected sealed override void Run()
            {
                base.Run();
            }
        }
    

    Car 类中定义了虚方法 Run , MyCar 类继承 Car 类,并覆写 Run 方法,同时使用 sealed 关键字,使得再继承 MyCar 类的子类,不能再覆写 Run 方法。

    这里我写一个 OtherCar 类并继承 MyCar 类,然后强制覆写 Run 方法,会如何呢?如下截图所示
    在这里插入图片描述
    注:这里我将成员声明为 protected ,只允许当前类和派生类访问,其它外部对象无法访问。


    结束语

    如果这篇博客有幸帮到了您,欢迎点击下方链接,和更多志同道合的伙伴一起交流,一起进步。

    Web开发者俱乐部

    展开全文
  • 如何定义一个不能被继承

    千次阅读 2016-11-08 21:19:41
    如何定义一个不能被继承???  假设有一个B,如果把B的构造函数声明为私有的,那么B这个不能被继承,但是这也引入了一个问题,不能外定义B类型的对象,那要怎么解决这个问题呢??? 方法...
  • 如何让一个类不能被继承

    千次阅读 2015-12-03 11:56:36
    要想让一个类不能被继承,已知方法有两种。一是,将类的构造函数定义为带private属性。二是,将该类虚继承一个父类,但是该父类的构造函数是带private属性的。 关于第二个方法可行的依据是: 1)派生类不能调用...
  • 首先你要知道自己为什么要用final,用final干什么! 6.8.2 final方法 之所以要使用final方法,可能是出于对两方面理由的考虑。...这是final的规定当你将final用于身上时,一个final是无法任何人继承的,那也就意
  • 哪些成员函数不能被继承

    千次阅读 2019-03-27 21:15:35
    C++中,并不是所有的成员函数都能被子类继承,有三成员函数不能被子类继承,分别是:构造函数(包括拷贝构造)、析构函数、赋值运算符重载函数。 1. 构造函数  构造方法用来初始化的对象,与父类的其它成员...
  • 不能被继承

    千次阅读 2012-06-07 11:50:09
    如何使类不能被继承 如果大家熟悉java的话应该知道java中有一种类不能被继承,那就是final类.这种类有很多用处,尤其是在大的项目中控制类的继承层次. 使子类数量不至于爆炸.在使用了多继承的类层次中这也是防止出现...
  • String为什么不能被继承

    千次阅读 2020-03-26 17:34:38
    我们都知道String类不能被继承,但为什么不能却不能回答地很完整。 首先我们可以看下String的源码(部分): public final class String implements java.io.Serializable, Comparable<String>, CharSequence { ...
  • jdk中哪些类不能继承

    千次阅读 2014-02-13 13:22:47
    不能继承的是是那些用final关键字修饰的。一般比较基本的类型或防止扩展无意间破坏原来方法的实现的类型都应该是final的,在jdk中System,String,StringBuffer等都是基本类型。 为什么我继承非fianl修饰的...
  • java中final修饰的类不能被继承

    千次阅读 2018-11-05 17:29:23
    final方法 之所以要使用final方法,可能是出于对两方面理由的考虑。第一个是为方法“上锁”,防止任何继承类改变它的本来含义。设计程序时,若希望一个方法的...不变,而且覆盖或改写,就可以采取这种做法。 ...
  • 【c++】实现一个不能被继承

    千次阅读 2017-04-20 20:25:13
    C++如何设计一个类,是该类不能被继承?利用私有构造函数,友元和虚继承的特性来实现
  • 面试题28:不能被继承

    千次阅读 2017-06-13 22:24:52
    在Java中同样也有关键字final表示一个类不能被继承。C++11提供final关键字使得类不能够被继承。那么,如何自己实现一个不被继承的类?常规的解法是,把类的构造和析构函数都设置为private即可,然后公有派生;这是...
  • 不能被继承(模板参数友元) 代码(C++)本文地址:http://blog.csdn.net/caroline_wendy题目: 用C++设计一个不能被继承.可以使用模板模板参数友元, 模板私有构造函数, 继承这个模板, 如果类被其他...
  • Java中不能被继承

    千次阅读 2016-12-12 21:04:06
    //java.lang包中不能被继承: public final class Byte public final class Character public static final class Character.UnicodeBlock public final class Class public final class Compile public final ...
  • C++定义不能被继承

    千次阅读 2012-12-22 12:51:26
    C++的定义的要求不能被继承,貌似最简单的想法是将构造函数定义为私有的,但事实上这样并不对,这会引发一个问题,用户如何实例化该?因为友元关系是不能够被继承的,所以可以考虑友元+私有化构造函数来实现。 ...
  • 抽象类不能继承接口

    千次阅读 2017-09-21 10:21:43
    1. 抽象可以继承普通,但可以继承接口。 (public abstract class 抽象 extends 普通 { }) 2. 接口可以继承多接口,但可以继承抽象。 (public abstract class 接口1 extends 接口2,接口3 ,接口4{ }...
  • 用c++设计一个不能被继承

    千次阅读 2017-08-02 12:16:42
    在Java 中定义了关键字final ,final 修饰的类不能被继承。但在C++ 中没有final 这个关键字,要实现这个要求还是需要花费一些精力。 首先想到的是在C++ 中,子类的构造函数会自动调用父类的构造函数。同样,子类...
  • C++中定义一个不能被继承

    千次阅读 多人点赞 2015-08-31 10:56:16
    最开始是从构造函数开始着手(先声明这种方法不能定义一个不能被继承,这是一种错误的方法,但是很容易往这方面想),假设存在下面的继承体系: 现在假设B是一个不能被继承,那么如果存在B的子类C,那么C的...
  • C++继承(1) - 基类哪些数据会被子类继承下来
  • String 不能被继承原因

    千次阅读 2019-01-24 16:22:57
    String类被final修饰不能被继承
  • 父类的构造器能不能被子类继承

    千次阅读 2018-03-05 18:19:08
    构造器是无法被继承的,所以不能重写,但是可以重载。原因:构造器是生产对象的一个途径,假如可以被继承,那么对象就可以复制了。子类可以通过继承构造器产生父类对象,这样就会出现子类引用指向父类对象,java是...
  • String类能被继承吗?为什么

    千次阅读 2019-07-09 07:54:32
    1、修饰类当用final去修饰一个类的时候,表示这个类不能被继承。注意:a. final修饰的类,final类中的成员变量可以根据自己的实际需要设计为fianl。b. final类中的成员方法都会隐式的指定为final方法。说明:在...
  • C++体系中,不能被派生类继承的有? 构造函数不能被继承,但是可以调用。派生的构造函数在初始化列表中应调用基类的构造函数。 --------------------- 为什么C++赋值运算符重载函数不能被继承? 这个问题...
  • 用C++设计一个不能被继承

    千次阅读 2011-06-17 11:05:00
    在C#中定义了关键字sealed,sealed修饰的类不能被继承。在Java中同样也有关键字final表示一个类型不能被继承。在C++中没有类似于sealed和final的关键字,所以我们只有自己来实现。  很多人都能够想到,类的构造...
  • String是所有语言中最常用的一个。我们知道在Java中,String是可变的、final的。... 若 String 允许被继承, 由于它的高度使用率, 可能会降低程序的性能,所以 String 定义成 final。   一:St
  • 枚举类能继承吗?能继承吗?

    千次阅读 2019-07-19 00:38:25
    枚举的作用:限定“数据集”中...1.枚举也是,也可以有自己的成员变量,成员方法,静态方法、静态变量等,也能实现其他的接口,不能继承其他了(因为已经继承了java.lang.Enum)。枚举的对象默认都是public...
  • 对于不能被继承,怎么初始化及销毁它的实例?”这是ADOBE公司的一道笔试题。 看了这道题目,笔者查阅了一些资料并结合自己的一些想法,写了这篇博客,有错误的地方请指出,谢谢。 首先看怎么防止类被...
  • 理解父类构造方法不能被子类继承

    千次阅读 2018-07-07 14:14:27
    Constructor&lt;? e&gt; constructor = aclass...aclass extends bclass注意:通过实验证明,父类的构造方法 不能被子类继承,例如bclass 有构造方法b(context,viewgroup)aclass没有构造方法a(context,viewg...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,233,576
精华内容 493,430
关键字:

哪些类不能被继承