我需要禁止用户调用class T
的常规构造函数,如下所示:
T obj (a, b, c); // Compile-time error
T* objPtr = new T (a, b, c); // OK
是否可以在C ++中使用?
答案 0 :(得分:2)
您可以使用factory pattern来模仿 kinda 的行为:用于实例化对象实例的friend class
:
class T;
class TMaker
{
public:
static std::unique_ptr<T> MakeT(int a, int b, int c);
};
class T
{
public:
void PrintMe() { std::cout << a << ", " << b << ", " << c << std::endl; }
private:
T(int a_, int b_, int c_) : a(a_), b(b_), c(c_) {}
int a, b, c;
friend class TMaker;
};
std::unique_ptr<T> TMaker::MakeT(int a, int b, int c)
{
return std::unique_ptr<T>{new T{a, b, c}};
}
现在,用户无法再直接构建您的类:
T v { 1, 2, 3 }; // doesn't work
T* v = new T{1, 2, 3}; // also doesn't work
相反,他们只能使用以下内容:
std::unique_ptr<T> t = TMaker::MakeT(1, 2, 3);
但请注意,您可能只有XY problem。
答案 1 :(得分:0)
像Tas指出的那样,你需要使用工厂。但我认为班级本身的简单工厂功能就足够了。
#include <iostream>
#include <memory>
template <class C>
struct creator
{
template<typename... Args>
static std::unique_ptr<C> create(Args&&... args)
{ return std::unique_ptr<C>( new C(std::forward<Args>(args)...) ); }
};
class MyClass : public creator<MyClass>
{
private:
friend class creator<MyClass>;
MyClass(int) { std::cout << "Created"; }
};
int main()
{
auto p = MyClass::create(0);
return 0;
}
由于你很可能不想重复自己,你可以创建一个有用的小模板Mixin(就像我上面所做的那样)。这将为您节省为您所做的每个类键入相同样板代码的工作。另一个好处是,使用模板将为应用程序中的所有类提供一致的接口和命名约定,这需要以相同的方式运行。
我们都知道,软件的一致性很好。
答案 2 :(得分:0)
将析构函数设为私有,并提供删除功能。这将使你的两个陈述都有效。
class T
{
public:
void PrintMe();
T(int a_, int b_, int c_);
void deleteMe() { delete this;}
private:
~T(){}
int a, b, c;
};