如何将一个类的构造函数的调用限制为仅限于其工厂类?

时间:2017-01-10 22:12:27

标签: c++ factory friend

我想防止除了我班级的工厂之外的任何东西构建我班级类型的对象。我需要该类具有公共接口,但我想将其创建仅限于其工厂。我该怎么做?

我们打电话给班级Car和工厂CarFactory。以下是我最初的想法,即如何在不使用friend的情况下执行此操作并将所有私有成员公开给工厂:

class Car {
private:
  Car();
  Car(Car& ref);

  friend class CarFactory;
};

class CarFactory {
public:
  Car * makeCar();
};

我发现了一个与Java相关的问题:How do I make a constructor available to only the factory class?

上面的代码按原样运行。为了澄清,我想知道是否有办法只与工厂共用构造函数而不是所有私有成员?

2 个答案:

答案 0 :(得分:4)

根据您的评论,我假设您正在寻找朋友的功能。可以找到有关宣布朋友的帮助here。以下是您修改的示例。

// Forward declare car
class Car;

class CarFactory {
public:
    Car * makeCar();
    Car * makeTruck();
};

class Car {
private:
    Car();
    Car(Car& ref);

    friend Car * CarFactory::makeCar();
};

Car * CarFactory::makeCar() {
    return new Car();
}

Car * CarFactory::makeTruck() {
    return new Car(); // Fails to compile
}

编辑:您在评论中询问了解决方案,其中只有Car的构造函数可供工厂使用。您需要定义一个只能由您想要的方法使用的新实用程序类,然后对要保护的每个方法使用该类。我个人认为这种方法很笨重,但它确实有效。

class Car {

public:
    struct t_private{
    private:
        t_private() = default;
        friend Car * CarFactory::makeCar();
    };

    Car(t_private);

private:
    Car(Car& ref);
};

Car * CarFactory::makeCar() {
    return new Car(Car::t_private{});
}

只有CarFactory可以构建Car,因为其他人无法创建Car::t_private,因为它的构造函数是私有的。 CarFactory无法访问Car的私人成员,因为它不是朋友。

答案 1 :(得分:-1)

使Car成为一个抽象类,然后在工厂内将其作为私有类实现:

class Car {
  public:
    virtual void drive()=0;
};
class CarFactory {
  private:
    class CarImp : public Car {
      ...
    };
  public:
    Car *makeCar() { return new CarImp(); }
}