关于C++停止类被继承的方法

这个问题已经被老生常谈了,一共有2中方案,但是今天写内部类时,想到另一种方案,通过内部类实现停止类继承;

首先来回顾前两种方案:

1、C++11语法,final关键字

 1 class A1{
 2     public:
 3      A1(){};
 4         ~A1(){};
 5 };
 6 
 7 class B1 final:public A1{//禁止B1被继承
 8 
 9 };
10 
11 class C1:public B1{//错误,
12 
13 };

编译情况:

2、构造函数私有化

2.1直接将构造函数私有化,这种方案有一个问题,只是达到禁止继承的目的,但是该类也无法创造出自己的对象;

 1 class A1{
 2     //public:
 3     private:
 4         int a;
 5         A1(int b):a(b){};
 6     public:
 7     ~A1(){};
 8 };
 9 
10 class B1 :public A1{
11 
12 };
13 
14 
15 
16 int main(){
17     A1 a1=new A1(6);
18     //B1 *b1=new  B1();
19     return 0;
20 }

编译器提示类A1也无法创建出对象;

 

 

 2.2利用友元,定义一个基类,将基类构造函数私有化

 1 class B1;
 2 
 3 class A1{
 4     //public:
 5     private:
 6     int b;
 7         A1(int a):b(a){};
 8         ~A1(){};
 9         friend class B1;
10     public:
11     int get(){return b;};
12 };
13 
14 class B1 :public  A1{
15     public:
16         B1(int a):A1(a){};
17 };
18 
19 class C1:public B1{
20     public:
21     C1(int a):B1(a){};
22 };
23 
24 int main(){
25     C1 b1(10);
26     cout<<b1.get()<<endl;
27     //C1 c1;
28 }

上述代码,并不能防止B1被继承,因为C1会调用B1的构造函数,而B1调用A1,然而B1是A1的友元类,所以代码可以通过,输出结果为10;

解决上述情况只需要成为虚基类即可,因为多个类继承自同一个基类时,共享同一个基类,为了防止基类被多次初始化,基类的初始化任务必须由继承体系中最底层的类完成;

修改完代码:

 1 class B1;
 2 
 3 class A1{
 4     //public:
 5     private:
 6     int b;
 7         A1(int a):b(a){};
 8         ~A1(){};
 9         friend class B1;
10     public:
11     int get(){return b;};
12 };
13 
14 class B1 :public virtual A1{
15     public:
16         B1(int a):A1(a){};
17 };
18 
19 class C1:public B1{
20     public:
21     C1(int a):B1(a){};
22 };
23 
24 int main(){
25     C1 b1(10);
26     cout<<b1.get()<<endl;
27     //C1 c1;
28 }

编译时报错:

 

 

3、内部类方案

class C
{
private:
    /* data */
    int a;
public:
    C(/* args */){};
    C(/* args */int c):a(c){};
    int get(){return a;}
    ~C(){};
};
class A{
    public:
        class B:public C//内部类,当为public时可以被继承,
        {
        private:
            /* data */
        public:
            B(/* args */):C(0){};
            explicit B(int b):C(b)  {} ;
            ~B(){};
        };
     private: 
};


class D:public A::B{
    public:
    D(int c):A::B(c){};
    ~D(){};
};


int main(){
   D d(10);
   cout<<d.get()<<endl;
}

运行结果为:

 

 将内部类访问属性私有化:

 1 class A{
 2     public:
 3     private: 
 4         class B:public C//内部类,当为public时可以被继承,
 5         {
 6         private:
 7             /* data */
 8         public:
 9             B(/* args */):C(0){};
10             explicit B(int b):C(b)  {} ;
11             ~B(){};
12         };
13      
14 };

编译结果为:

只不过这一种方案,需要在内部类的外部类定义接口访问内部类,属实繁杂,不过这也是一种实现方案,示例代码为;

 1 class C
 2 {
 3 private:
 4     /* data */
 5     int a;
 6 public:
 7     C(/* args */){};
 8     C(/* args */int c):a(c){};
 9     int get(){return a;}
10     ~C(){};
11 };
12 class A{
13     private: 
14         class B:public C//内部类,当为public时可以被继承,
15         {
16         private:
17             /* data */
18         public:
19             B(/* args */):C(0){};
20             explicit B(int b):C(b)  {} ;
21             ~B(){};
22         };
23      B b;
24      public:
25      A(int a):b(a){};
26     int get(){return b.get();};
27 };
28 int main(){
29    A a(10);
30    cout<<a.get()<<endl;
31 }

 

 

最后感谢博主:https://blog.csdn.net/renwotao2009/article/details/6596710

posted @ 2021-05-28 11:30  LifeRunningError  Views(679)  Comments(0Edit  收藏  举报