C ++ 11引入了关键字final
以禁止未来覆盖或禁止继承。可以使用它的最常见示例是针对不打算用作基类的类的情况(例如具有非虚拟析构函数)。但是,有时我们可能希望在两个类(即private
继承)之间存在 is-implemented-in-terms-of 关系,而不是是-a 关系(public
继承)。但是,final
禁止这两种类型的继承。
我的问题如下:是否有任何方法允许private
继承但禁止public
继承(可能不是直接,但至少可以“模拟”它)?在这种情况下,即使我们使用具有非虚析构函数的类也不会有任何问题,因为我们不能通过指向base的指针直接使用派生类,所以我们应该没问题。
我正在考虑这样的代码:
class Base /*final*/ {}; // making it final prohibits both private and public inheritance
class PrivateDerived: private Base{}; // this should work
class PublicDerived: public Base{}; // this shouldn't
int main()
{
PrivateDerived prvd;
PublicDerived pubd; // this should not compile
// Base* pBase = new PrivateDerived; // doesn't work, so we are ok
}
答案 0 :(得分:4)
有趣的问题!如果你不介意放弃析构函数的琐事,我认为以下工作可以做到:
#include <type_traits>
template <typename T>
class Base {
protected:
~Base() {
static_assert(!std::is_convertible<T*,Base*>::value, "Invalid use of public inheritance.");
}
};
class Derived : public Base<Derived> {
};
int main() {
Derived d;
}
上面的代码无法编译:{{1}}触发,因为static_assert
可转换为Derived*
。但是,如果将继承更改为Base<Derived>*
或protected
,则代码将编译。
不幸的是,用户仍然可以用脚射击自己:
private
答案 1 :(得分:0)
我不确定这是否是您正在寻找的,或者这对您的情况是否有帮助。然而,我将证明多态行为。
受保护的构造函数抽象类
class BaseProtected {
// ----- Member Variable Section -----
public:
// There Shouldn't Be Public Variables In A Base Class Unless
// That Is The Behavior You Are Looking For - Keep In Mind
// Every Inherited Class & Outside Class Can Change Them.
protected:
// Member Variables Here To Be Shared With Each Derived Class
private:
// Member Variables Here To Be Used By Base Class Only
// ----- Member Function Section -----
public:
virtual ~BaseProtected(); // Virtual Destructor
void somefunc() const; // Common Function Between All Derived Class
virtual void allDerivedMustImplement() const; = 0 // Purely Virtual
protected:
// Default Constructor - Can Not Declare An Instance Of Base Class
BaseProtected(); // Abstract Class
// Protected Functions Shared Between Classes
// Protected Functions That Are Purely Virtual If Needed
private:
// Private Functions Used By Base Class Only
}; // BaseProtected
具有可能继承的派生类
class DerivedWithPossibleInheritance : public BaseProtected {
// ----- Member Variable Section -----
public:
// Public Member If Giving Free Access
protected:
// Protected Members If Being Inherited From
private:
// Private Members Unique To This Derived Class
// ----- Member Function Section -----
public:
DerivedWithPossibleInheritance(); // Default Constructor
virtual ~DerivedWithPossibleInheritance(); // Virtual Destructor
void uniqueFunctionForThisClass() const;
void allDerivedMustImplement() const override;
private:
// Private Functions Unique To This Class
}; // DerivedWithPossibleInheritance
无法继承的派生类
class DerivedClassCanNotBeInheritedFrom sealed : public BaseProtected {
// ----- Member Variable Section -----
public:
// Public Members Variables
protected:
// Should Not Have Member Variables Here For This Class Can Not Be Inherited from
private:
// Private Members Variables
// ----- Member Function Section ------
public:
DerivedClassCanNotBeInheritedFrom(); // Default Constructor
virtual ~DerivedClassCanNotBeInheritedFrom(); // Default Virtual Destructor
void anotherUniqueFunctionForThisClass() const;
void allDerivedMustImplement() const override;
protected:
// There Should Not Be Any Functions Here This Can Not Be Inherited From
private:
// Private Member Functions Here
}; // DerivedClassCanNotBeInheritedFrom
我在这里演示的是使用继承和多态时密封的关键词。如果您不希望从中派生类,请使用sealed关键字。
对于声明任何基类,独立类或具有私有构造函数的单例类,需要使用friend关键字。这里有很多类型的实现可以用来显示它们,但是防止类继承的概念是相同的。我个人没有使用关键字final,但我使用了关键字密封,它非常好用。
我没有使用除了public之外的类的继承:所以,就保护或私有继承而言,回答你的问题不是我真正熟悉的。但也许使用密封关键字可能对您有所帮助。