在c ++中,“保护”修饰符仅允许在派生类中进行方法调用。是否有可能实现逆逻辑-禁止在派生类中调用基类方法?下面的代码说明了我想要得到的。
class Base
{
int data;
protected:
// This constructor should be called only in the derived classes
Base(int d): data(d) { }
public:
// This construcor can be called wherever except a derived classes!
Base(): data(0) { }
};
class Derived : public Base
{
public:
// The developer must not forget to initialize "data"
Derived() : Base(10) {}
// I want to get a compilation error there
Derived() : Base() {}
};
答案 0 :(得分:2)
是否可以禁止在派生类中调用基类方法?
是的。通过使用专用访问说明符。私有名称只能由该类本身访问。
这不是反逻辑。不可能减少派生类对公共名称的可访问性。
答案 1 :(得分:2)
// This construcor can be called wherever except a derived classes!
没有办法做到这一点。公共函数可以被任何人调用,并且如果派生类调用该函数,则没有SFINAE技巧可以停止它,因为构造函数不知道从何处调用它。
答案 2 :(得分:1)
这似乎是XY问题。尽管我不建议这样做(我建议重新考虑设计),但我还是发现了(无论好坏)受CRTP模式启发的解决方案:
template <class D = void>
class Base
{
protected:
int data;
protected:
// This constructor should be called only in the derived classes
template <class Der = D, class = std::enable_if_t<std::is_base_of_v<Base, Der>>>
Base(int d): data(d) {}
public:
// This constructor can be called wherever except a derived classes!
template <class Der = D, class = std::enable_if_t<!std::is_base_of_v<Base, Der>>>
Base(): data(0) { }
};
class Derived : public Base<Derived>
{
int mydata = 1;
public:
// The developer must not forget to initialize "data"
Derived() : Base(24) {}
// I want to get a compilation error there
//Derived() : Base() {} // (1) compilation error here
};
auto test()
{
Base b1{};
//Base b2{24}; // (2) compilation error here
Derived d{};
}
当然有这个问题。对于初学者来说,创建派生类为class Derived : public Base<void>
并没有阻止。
如果需要,您可以添加一个通用的基类
class Base_l0
{
};
template <class D = void>
class Base_l1 : Base_l0
{
};
class Derived : public Base_l1<Derived>
{
};
答案 3 :(得分:0)
简短的回答是“否”。
在C ++中,只有public
protected
和private
。没有回旋的余地。您可以从任何地方(public
),从类本身(private
)之外的任何地方或从类及其子级(protected
)来访问函数。
我只想强迫用户在继承[sic]之前执行一些其他操作。例如,为避免随机错误。
如果调用默认构造函数会在从其继承的同时调用它而导致错误,那么很可能在您不从其继承时导致错误。这意味着您可能根本不应该将此构造函数公开,