Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforce a protected constructor in deriving class

Is there any mechanism that allows to enforce a protected constructor in a deriving class?

Simple example:

template<typename T>
class Factory;

class Base {
  template<typename T>
  friend class Factory;
protected:
  Base();
};


class Child : public Base {
public:
  Child(); // this should lead to a compile time error
};

<template T>
class Factory {
Base* GetNew()
{
  BOOST_STATIC_ASSERT(boost::is_base_of<Base, T>::value);

  Base* b = new T();
  b->doStuff();

  return b;
 }
};

So I want the Child class to be only creatable by the factory and enforce that all child classes deriving from Base have a protected constructor.

like image 553
Chris Avatar asked Oct 22 '15 11:10

Chris


People also ask

What happens if a constructor is declared protected?

Protecting a constructor prevents the users from creating the instance of the class, outside the package. During overriding, when a variable or method is protected, it can be overridden to other subclass using either a public or protected modifier only. Outer class and interface cannot be protected.

Can we use protected in constructor?

Modifiers public, protected and, private are allowed with constructors. We can use a private constructor in a Java while creating a singleton class.

Can we instantiate the object of derived class if the parent constructor is protected?

Can we instantiate the object of derived class if parent constructor is protected ? Ans. Yes, as protected constructor is accessible in sub class.

Can we declare constructor as protected in C++?

Typically, constructors have public accessibility so that code outside the class definition or inheritance hierarchy can create objects of the class. But you can also declare a constructor as protected or private . Constructors may be declared as inline , explicit , friend , or constexpr .


2 Answers

No, there's no way to enforce this. In general, base classes are very limited in how they can constrain subclasses. Base is not, and should not try to be, responsible for policing everyone who might ever write a class that happened to inherit from Base.

like image 146
Sneftel Avatar answered Oct 13 '22 01:10

Sneftel


Short answer, no kind of.

protected is the least useful access specifier since any derived class is free to make the name (including the name of a constructor) public.

What you can do is use an access key in the constructor to ensure that only a factory creates the class.

struct factory;

// create_key's constructor is private, but the factory is a friend.
class create_key
{
  create_key() {};
  friend factory;
};

struct only_from_factory
{
  // base constructor demands a key is sent. Only a factory may create a key.
  only_from_factory(const create_key&) {};
};
like image 36
Richard Hodges Avatar answered Oct 13 '22 01:10

Richard Hodges