检查子类的构造函数在 C++ 中是否为 public
Check if constructors of subclass are public in C++
希望这不会重复,但未能找到完美的解决方案。是否可以说特殊基class 的subclasses 只能在模板工厂函数中创建?为了简单起见,我只想在基础 class 中强制执行此行为。这是一个简单的例子:
template <class T>
T* createBase();
template<typename T>
class Base {
protected:
template <class T>
friend T* createBase();
static T* create()
{
return new T();
}
};
class TestClass1 : public Base<TestClass1>
{
public:
TestClass1() : Base() {}
};
template <class T>
T* createBase()
{
static_assert(std::is_base_of<Base<T>, T>::value, "use the createBase function only for Base<T> subclasses");
return Base<T>::create();
}
实际上这是允许的:
TestClass2 *testClass = createBase<TestClass2>();
TestClass2 tester;
但我只想拥有这个:
TestClass1 *testClass = createBase<TestClass1>(); //allowed
TestClass1 tester; // compile error
当然我知道我只需要将 TestClass1 的构造函数放在 private
或 protected
中。但如果在 Base 对象中这样说,那就太好了。
编辑:
当 subclass 的构造函数为 public 时出现编译错误也是一个不错的解决方案。也许用 static_assert().
即使使用 CRTP,您也无法从基础 class 控制构造函数的可访问性。
你可以做的是在基本构造函数中添加一个 static_assert 检查 T
a.k.a 派生的 class 是否没有可公开访问的默认构造函数:
template <class T>
class Base {
public:
Base() {
static_assert(!std::is_default_constructible<T>::value,
"T must not be default constructible");
}
};
static_asswert
不适用于 class 范围,原因如下所示:
希望这不会重复,但未能找到完美的解决方案。是否可以说特殊基class 的subclasses 只能在模板工厂函数中创建?为了简单起见,我只想在基础 class 中强制执行此行为。这是一个简单的例子:
template <class T>
T* createBase();
template<typename T>
class Base {
protected:
template <class T>
friend T* createBase();
static T* create()
{
return new T();
}
};
class TestClass1 : public Base<TestClass1>
{
public:
TestClass1() : Base() {}
};
template <class T>
T* createBase()
{
static_assert(std::is_base_of<Base<T>, T>::value, "use the createBase function only for Base<T> subclasses");
return Base<T>::create();
}
实际上这是允许的:
TestClass2 *testClass = createBase<TestClass2>();
TestClass2 tester;
但我只想拥有这个:
TestClass1 *testClass = createBase<TestClass1>(); //allowed
TestClass1 tester; // compile error
当然我知道我只需要将 TestClass1 的构造函数放在 private
或 protected
中。但如果在 Base 对象中这样说,那就太好了。
编辑:
当 subclass 的构造函数为 public 时出现编译错误也是一个不错的解决方案。也许用 static_assert().
即使使用 CRTP,您也无法从基础 class 控制构造函数的可访问性。
你可以做的是在基本构造函数中添加一个 static_assert 检查 T
a.k.a 派生的 class 是否没有可公开访问的默认构造函数:
template <class T>
class Base {
public:
Base() {
static_assert(!std::is_default_constructible<T>::value,
"T must not be default constructible");
}
};
static_asswert
不适用于 class 范围,原因如下所示: