C#中,被关键字sealed修饰的类不可被继承。
Java中,被关键字final修饰的类不可被继承。
C++中,子类会自动调用父类的构造函数,也会自动调用父类的析构函数,为了让此类不被继承,可以将该类的构造函数和析构函数设置为私有的。如下:
设计一个类不能被继承
//设计一个类不能被继承
class A
{
private:
A()
{
cout << "A()" << endl;
}
~A()
{
cout << "~A()" << endl;
}
};
class B :public A
{
public:
B()
{
cout << "B()" << endl;
}
~B()
{
cout << "~B()" << endl;
}
};
设计一个类只能在栈上创建对象
只有使用new运算符,对象才会建立在堆上,所以只要禁用new运算符就可以实现类对象只能建立在栈上,将operator new()设为私有就可以了,一定要记得,重载了new就要重载delete
//设计一个类只能在栈上创建对象
class A
{
public:
A()
{}
~A()
{}
private:
void* operator new(size_t);
void operator delete(void *ptr);
};
设计一个类只能在堆上创建对象
类对象只能建立在堆上,就是不能静态建立对象,即不能直接调用类的构造函数。
可以把类的构造函数声明为私有,就无法在类的外部调用类的构造函数建立对象,只能使用new运算符来建立对象。前面已经说过,new运算符的执行过程分为两步,C++提供new运算符的重载其实只是允许重载operator new()函数,不能重载new运算符,而operator new()函数只用于分配内存,无法提供构造函数,所以,我们再定义一个GetObj函数,用于在堆上new对象,通过GetObj函数,建立的对象都是在堆上的new出来的,将函数声明为静态的,就可以通过域作用访问符访问GetObj函数,在堆上建立对象。
//设计一个类只能在堆上创建对象
class A
{
public:
static A& GetObj(int a1, int a2)
{
return *(new A(a1, a2));
}
private:
A(int a1,int a2)
:_a1(a1)
, _a2(a1)
{}
int _a1;
int _a2;
};
c++是一个静态绑定的语言,在编译过程中,所有的非虚函数都必须分析完成,即使是虚函数,也需检查可访问性,因此,当在栈上生成对象是,对象会自动析构,也就是说析构函数必须可访问,而对上生成对象,由于析构是由程序员控制,所以,就可以不用析构函数,而重新定义一个函数完成析构函数的功能,然后手动调用。故可以
把析构函数声明为私有的,但为了能够被继承,故声明为保护的。
class C
{
public:
C()
{}
protected:
~C()
{}
};