2016-10-26 3 views
0

Я хочу заставить детей базового класса иметь частные конструкторы. Затем я хочу, чтобы эти конструкторы вызывались через класс друзей, который является фабричным классом. Это мой шаблон использования:Как принудительно использовать частные конструкторы в дочерних элементах базового класса

У меня есть базовый класс:

class Base: 
    virtual double method1(); 

Child Я хочу, чтобы наследовать Base:

class Child::Base : 
    public: 
    Child(string s) { 
     //do something 
    } 

    double method1() { 
      return field1; 
    } 

    private: 
    double field1; 
} 

Дети Base будет создан путем анализа string. Поэтому у меня мог бы быть конструктор Base, который принимает string. Но я не могу сделать конструкторы виртуальными и, следовательно, не применять параметры.

Таким образом, в целях обеспечения того, чтобы дети Base могут быть созданы только от входа string, я хочу детей Base быть обработан из класса фабрики. Моя проблема заключается в том, что ничто не мешает кому-то создавать экземпляр Child отдельно. Поэтому я хочу, чтобы конструкторы детей из Base были частными, а затем у вас был класс фабрики как класс друга.

Любые идеи? Даже комментарии к этому проекту приветствуются.

PS: Чтобы получить от строки до экземпляра Child, будет отличаться для каждого ребенка.

+0

я не получил корень вашего вопроса ясно, что если вы говорите: «Я хочу, чтобы дети базы, чтобы всегда FIELD1» почему бы не просто двигаться field1 в базовый класс тогда? –

+0

изменил вопрос. Я пытался абстрагировать вопрос на простой пример, но, очевидно, я потерпел неудачу. –

+0

Вы можете пометить конструктор по умолчанию для Base private, поэтому конструктор Child будет вынужден вызывать тот, который у вас есть со строкой в ​​качестве параметра, или получить ошибку «нет подходящего конструктора по умолчанию (C2512)» –

ответ

2

Вы можете запретить создание производных классов, не заставляя их конструкторы быть закрытыми, а заставляя их быть абстрактными. Вот рабочий пример:

class A 
{ 
    private: 
     struct secret{}; 
     virtual void impossible(secret) = 0; // cannot override this in subclasses 
              // because the parameter type is private 

     template <class X> class AImpl : public X 
     { 
      void impossible(secret) {}; // a nested class can access private members 
     }; 

     template<class X> friend X * AFactory(); 

    public: 
     virtual ~A() {} 
}; 

class B : public A 
{ 
    // void impossible(A::secret) {}; -- can't do that, A::secret is private! 
}; 

template <class X> 
X * AFactory() 
{ 
    return new A::AImpl<X>; 
}; 

int main() 
{ 
    // B b; -- can't do that, B is abstract! 
    B* pB = AFactory<B>(); // Ok 
} 
Смежные вопросы