在C ++中使用new()作为构造函数

时间:2016-04-03 07:20:46

标签: c++ constructor new-operator

我需要禁止用户调用class T的常规构造函数,如下所示:

T obj (a, b, c); // Compile-time error
T* objPtr = new T (a, b, c); // OK

是否可以在C ++中使用?

3 个答案:

答案 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;
};