这是另一种依赖于检查派生类构造函数是否是私有的方法。但说实话,我更喜欢@caleth给出的解决方案
#include <type_traits>
#include <iostream>
#include <type_traits>
template<typename T, typename... Args>
struct constructor_tag{};
class A{
protected:
template<typename T, typename... Args>
A(constructor_tag<T, Args...>) {
static_assert(!std::is_constructible_v<T, Args...>, "CONSTRUCTOR MUST NOT BE PUBLIC");
};
public:
template<class T, typename... ARGUMENTS>
static T* create(ARGUMENTS&&... arguments) {
return new T(std::forward<ARGUMENTS>(arguments)...);
}
};
class B : public A {
friend class A;
B() : A(constructor_tag<B>{}) {}
public:
};
class C : public A {
friend class A;
C () : A(constructor_tag<C>{}) {}
C(int) : A(constructor_tag<C, int>{}) {}
public:
};
// Following class will not compile because the constructor is public
//class D : public A {
// friend class A;
//
//public:
// D () : A(constructor_tag<D>{}) {}
//
//};
void test() {
// B b; //calling a private constructor of class 'B'
// C c(5);//calling a private constructor of class 'A'
A::create<B>();
A::create<C>(5);
A::create<C>();
}
int main() {
test();
}