小屋杂谈,记录日常
方法1:
如果想让这个类不能被继承,可以把这个类的构造函数设置成私有,这样子类去继承他构造就会报错,这样的话这个类就是不能被继承的,如果需要用这个类的对象的话,在基类里写个静态函数,内部实现new个对象,返回他的指针就行
(不推荐!)只能局限在堆上去构建这个对象,在栈上不行
代码示例
方法2:
(推荐回答的版本!)
想让这个类不能被继承,我们可以让这个类去虚继承一个父类(这个父类可以是任意的一个辅助的类),这个辅助的父类构造函数设置成private,然后让这个类去作为辅助父类的友元
这个时候你让一个子类去继承刚刚完成的这个类,用子类去构建对象就会失败了。因此说这个类是不能被继承的
讲一下依据:
- 派生类不能去调用父类的private属性的构造函数
- 建立一个对象时,如果这个对象中含有从虚基类继承来的成员,则虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的。
- 意思就是辅助类A的构造为私有,B虚继承A类,且B是A的友元,友元的话B就可以访问A的私有属性,因此B去栈上或者堆上去构建自己的对象都是可以的;而因为友元不能被继承下去,所以C类去继承B的时候,这个友元没有被继承下去,C类并不是A的友元,又因为B类是虚继承A类的,所以C在构建对象的时候直接跳到A类去调用A类的构造,因为A类的构造是私有属性,所以C构建对象就会失败。
- 这样的爷->父->子,一串就说明了父亲这个类是不能被继承的,要是被继承了,儿子就没法去构建对象了
代码模板:
template<typename T>
class A
{
friend T;//注意这里不需要class关键字 B是A的友元
private:
A() {}
~A(){}
};
class B :virtual public A<B>//虚继承A
{
public:
B(){}
~B(){}
};
class C:public B
{
};
int main()
{
B b;//栈上
B *bb = new B();//堆上
C c;//出错了就会 // 基类构造函数私有,不可以被继承。因此不可以创建栈上对象
}
不理解虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的戳下面
虚基类及其派生类的构造函数_
方法3:
c++11引入关键字final用来标识虚函数不能在子类中被覆盖(override),或一个类不能被继承
class A final
{
private:
A() {}
};
class B :public A
{
};
class A
{
public:
A() {}
virtual void fun()final{
cout << "A fun" << endl;
}
};
class B :public A
{
public:
void fun() {
cout << "B fun" << endl;
}
};
看完上面的就能回答下面这个问题了
如何实例化构造函数是private属性的类?
只要有一个函数能够访问private成员就行了。这个就有两种方法。
一是,在类中定义一个static 成员函数。
二是,在类中定义一个friend成员。