What are practical uses of a protected constructor? - c++

Why would anyone declare a constructor protected? I know that constructors are declared private for the purpose of not allowing their creation on stack.

When a class is (intended as) an abstract class, a protected constructor is exactly right. In that situation you don't want objects to be instantiated from the class but only use it to inherit from.
There are other uses cases, like when a certain set of construction parameters should be limited to derived classes.

Non-public constructors are useful when there are construction requirements that cannot be guaranteed solely by the constructor. For instance, if an initialization method needs to be called right after the constructor, or if the object needs to register itself with some container/manager object, this must be done outside the constructor. By limiting access to the constructor and providing only a factory method, you can ensure that any instance a user receives will fulfill all of its guarantees. This is also commonly used to implement a Singleton, which is really just another guarantee the class makes (that there will only be a single instance).
The reason for making the constructor protected, rather than private, is the same as for making any other method or field protected instead of private: so that it can be inherited by children. Perhaps you want a public, non-virtual factory method in the base class, which returns references to instances of the derived classes; the derived classes obviously want access to the parent constructors, but you still don't want to be creating them outside of your factory.

A protected constructor can be used to make a class effectively abstract when none of its methods are pure-virtual.
It is not quite abstract in the C++ sense since friend classes can still use it without overriding, but then you would have to declare these.

A protected constructor means that only derived members can construct instances of the class (and derived instances) using that constructor. This sounds a bit chicken-and-egg, but is sometimes useful when implementing class factories.

one use could be factory patterns

For factory methods with side-effects.
class mine {
private:
mine () {};
protected:
mine(int id) : m_id(id) {};
int m_id;
static int m_count;
public:
static mine* CreateOneOfMe() {
return mine(m_count++);
}
int GetId() { return m_id; }
};
This creates instances of the class and guarantees that each of them has a unique incrementing integer id. Note that if the constructor you want to use is not the default, you must hide the default too.

To let a subclass use a constructor that should not be accessible to an instantiator directly.

You could use it to limit the classes that could create it, for example:
class Level
{
private:
Level();
~Level();
friend class LevelManager;
};
The only class that can create an instance of it is the LevelManager class, so you will always know that the Level instance is created in the LevelManager.

One use of protected constructor is to implement the CRTP pattern, see the code below:
#include <iostream>
#include <assert.h>
template <class T>
class ComparableMixin {
public:
bool operator !=(ComparableMixin &other) {
return ~(*static_cast<T*>(this) == static_cast<T&>(other));
}
bool operator <(ComparableMixin &other) {
return ((*(this) != other) && (*static_cast<T*>(this) <= static_cast<T&>(other)));
}
bool operator >(ComparableMixin &other) {
return ~(*static_cast<T*>(this) <= static_cast<T&>(other));
}
bool operator >=(ComparableMixin &other) {
return ((*static_cast<T*>(this) == static_cast<T&>(other)) || (*(this) > other));
}
protected:
ComparableMixin() {}
};
class Integer: public ComparableMixin<Integer> {
public:
Integer(int i) {
this->i = i;
}
int i;
bool operator <=(Integer &other) {
return (this->i <= other.i);
}
bool operator ==(Integer &other) {
return (this->i == other.i);
}
};
int main() {
Integer i(0) ;
Integer j(1) ;
//ComparableMixin<Integer> c; //compilation error!
assert (i < j );
assert (i != j);
assert (j > i);
assert (j >= i);
return 0;
}

Related

Making Base Class Conversion Functions Public with a Protected Inheritance

I have a class inheriting from another. I don't want users of this class to accidentally use base-class functions on the child object. The obvious answer is to make the inheritance protected or private.
However, I do want implicit casting from the child object to the base class. The default implementation of this cast is hidden in most contexts as it's given the protected/private status, and attempting to define a user conversion throws the warning that
"converting ‘B’ to a reference to a base class ‘A’ will never use a type conversion operator [-Wclass-conversion]"
Fair enough. With that avenue closed to me, I must turn here and ask: is there some way to reclassify the default type conversion into the public space so that implicit casting can live on?
As an example of what I'm trying to get working:
class A
{
public:
A()
{
}
A(A& otherA)
{
}
};
class B : protected A
{
public:
operator A& ()
{
return *this;
}
};
int main() {
B guy;
A otherguy(guy);
}
Sadly, I can't just declare the offending functions within the base class as protected: I want them available if the user explicitly casts to that base class. In my particular case, B contains no data and is merely a convenience/safety wrapper around A, so I don't need to worry about slicing or otherwise losing any information by allowing this cast. I just don't want users mistaking the backend API (which is exposed currently via public inheritance) for parts of the more user-friendly wrapper API.
I don't think you can do what you want in the way you've asked to do it.
I'd use encapsulation instead of inheritance:
class A {
public:
T func1(); // should be visible via B
void func2(); // should not be visible via B
};
class B { // note: not inheriting from A
A base; // B explicitly defines its "base class sub-object"
public:
// provide access to base class sub-object
operator A&() { return base; }
// provide access to func1
T func1() { return base.func1(); }
};
void use(A &a) { a.func2(); }
int main() {
B b;
b.func1(); // no problem
// b.func2(); // won't work;
use(b); // no problem. Uses our conversion operator
}

Accessing private class member in operator overloading [duplicate]

I didn't think it was possible, but if you have two instances of the same class, are you allowed to access one's private members from the other?
Is this why you can also do this in copy constructors? in fact, is the copy constructor the reason this is allowed? Doesn't this break encapsulation?
Yes, any code within a class can access private data in any instance of the class.
This breaks encapsulation if you think of the unit of encapsulation as the object. C++ doesn't think of it that way; it thinks of encapsulation in terms of the class.
Access restrictions are a property of the class, not of an instance.
That's why you can write your usual copy constructor:
class Foo
{
int a; // private!
public:
Foo (Foo const & rhs) : a(rhs.a) { } // rhs.a is accessible
};
This idea is also what fuels the "factory" idiom:
class Bar
{
Bar() { } // private?!
public:
static Bar * create() { return new Bar(); } // Bar::Bar() is accessible
};

How to propagate friend for derived classes

I want to have a class hierarchy and be able to create objects from it only inside a Factory.
Example:
class Base
{
protected:
Base(){};
virtual void Init(){};
friend class Factory;
};
class SomeClass : public Base
{
public://I want protected here! Now it's possible to call new SomeClass from anywhere!
SomeClass(){};
void Init(){};
};
class Factory
{
public:
template<class T>
T* Get()
{
T* obj = new T();
obj->Init();
return obj;
}
};
int main()
{
Factory factory;
SomeClass *obj = factory.Get<SomeClass>();
}
My problem is that I want to be able to make objects only from Factory, but I don't want to declare friend class Factory in every class derived from Base.
Is there any way to propagate friend in derived classes? Is there any other way to achieve this behavior?
No, it's deliberately impossibile.
Is an issue by encapsulation.
Suppose to have a class "PswClass" that manage any password, that is cascade friend with other class: if I inherit from PswClass:
class Myclass : public PswClass {
.......
}
In this way I can, maybe, have access to field that it would be private.
Friendship is neither inherited nor transitive, as described here: friend class with inheritance.
After a little experimentation, and making some use of this hack How to setup a global container (C++03)?, I think I have found a way give the "factory" unique rights to create the objects.
Here's a quick and dirty code. (Scroll towards the bottom to see the hack.)
class Object {};
class Factory {
public:
// factory is a singleton
// make the constructor, copy constructor and assignment operator private.
static Factory* Instance() {
static Factory instance;
return &instance;
}
public: typedef Object* (*CreateObjectCallback)();
private: typedef std::map<int, CreateObjectCallback> CallbackMap;
public:
// Derived classes should use this to register their "create" methods.
// returns false if registration fails
bool RegisterObject(int Id, CreateObjectCallback CreateFn) {
return callbacks_.insert(CallbackMap::value_type(Id, createFn)).second;
}
// as name suggests, creates object of the given Id type
Object* CreateObject(int Id) {
CallbackMap::const_iterator i = callbacks_.find(Id);
if (i == callbacks_.end()) {
throw std::exception();
}
// Invoke the creation function
return (i->second)();
}
private: CallbackMap callbacks_;
};
class Foo : public Object {
private: Foo() { cout << "foo" << endl; }
private: static Object* CreateFoo() { return new Foo(); }
public:
static void RegisterFoo() {
Factory::Instance()->RegisterObject(0, Foo::CreateFoo);
}
};
class Bar : public Object {
private: Bar() { cout << "bar" << endl; }
private: static Object* CreateBar() { return new Bar(); }
public:
static void RegisterBar() {
Factory::Instance()->RegisterObject(1, Bar::CreateBar);
}
};
// use the comma operator hack to register the create methods
int foodummy = (Foo::RegisterFoo(), 0);
int bardummy = (Bar::RegisterBar(), 0);
int main() {
Factory::Instance()->CreateObject(0); // create foo object
Factory::Instance()->CreateObject(1); // create bar object
}
No, there is no way to inherit friend declaration from base class. However, if you make Base constructor private, instances of derived classes won't be possible to create without Factory help.
As others already said, friendship is not inheritable.
this looks like a good candidate of "Abstract Factory" pattern.
assume "SomeClass"es derived from base are used polymorphically.
declare a abstract factory base, which creates Base objects.
derive each concrete factory from base, override the base creation method...
see http://en.wikipedia.org/wiki/Abstract_factory_pattern for examples
You can't do that. This is done to protect encapsulation. See this post: Why does C++ not allow inherited friendship?
For future reference, another idea that came out of the chat between OP and me, which works with only one use of friend as the OP wanted. Of course, this is not a universal solution, but it may be useful in some cases.
Below code is a minimal one which shows the essential ideas. This needs to be "integrated" into the rest of the Factory code.
class Factory;
class Top { // dummy class accessible only to Factory
private:
Top() {}
friend class Factory;
};
class Base {
public:
// force all derived classes to accept a Top* during construction
Base(Top* top) {}
};
class One : public Base {
public:
One(Top* top) : Base(top) {}
};
class Factory {
Factory() {
Top top; // only Factory can create a Top object
One one(&top); // the same pointer could be reused for other objects
}
};
It is not possible. As others have said friendship is not inherited.
An alternative is to make all class hierarchy constructors protected and add the factory function/class as friend to all the classes you're interested in.

extending an object of a basic class to an object of a complex class

how can I do that? I thought of an method in the complex class which copies every variable of the basic object to the complex object, but that seems a little bit to inconvenient.
class Basic
{
//basic stuff
}
class Complex : public Basic
{
//more stuff
}
Basic * basicObject = new Basic();
//now "extending" basicObject and "cast" it to Complex type
//which means copy everything in basicObject to an complexObject
or something like:
Complex * complexObject = new Complex();
complexObject.getEverythingFrom(basicObject);
seems to be too inconvenient, because everytime I change the Basic class, I have to change this "copy" method too.
Define the values you want to share between the classes in protected section like so:
class Base
{
public:
int myPublicShared1;
int myPublicShared2;
Base& operator = (Base& other)
{
// Copy contents in base across
return *this;
}
protected:
int myShared1;
int myShared2;
private:
int notShared1;
int notShared2;
};
class Derived : public Base
{
public:
Derived& operator = (Derived& other)
{
Base::operator = (other);
// copy the rest of variables specific to Derived class.
}
Derived& operator = (Base& other)
{
Base::operator = (other);
}
// Derived now has all variables declared in Base's public and protected section
};
In C++, objects can not change their type.
So either you rewrite your program to right away create Complex objects, or you create a copy ctor so that you can do:
new Complex(*basicObject);
side note: from words like extend and the usage of new it seems you come from a java world. Don't make the mistake of thinking that how you do things in java is also how you do it in C++.

Call a base class constructor later (not in the initializer list) in C++

I'm inheriting a class and I would like to call one of its constructors. However, I have to process some stuff (that doesn't require anything of the base class) before calling it. Is there any way I can just call it later instead of calling it on the initializer list? I believe this can be done in Java and C# but I'm not sure about C++.
The data that I need to pass on the constructor can't be reassigned later, so I can't just call a default constructor and initialize it later.
Is there any way I can just call it later instead of calling it on the initializer list?
No, you cannot. The base class constructor must be called in the initializer list, and it must be called first.
In fact, if you omit it there, the compiler will just add the call implicitly.
I believe this can be done in Java and C# but I'm not sure about C++.
Neither C# nor Java allow this either.
What you can do, however, is call a method as an argument of the base class constructor call. This is then processed before the constructor:
class Derived {
public:
Derived() : Base(some_function()) { }
private:
static int some_function() { return 42; }
};
As was said by several people answering, you cannot delay the invocation of a base class constructor, but Konrad has given a good answer that might well solve your problem. However, this does have its drawbacks (for example, when you need to initialize several functions with values whose calculations share intermediate results), so just to be complete, here's another way of solving the problem of fixed initialization order, by using it.
Given the fixed order of initialization, if you have control over the derived class (and how else would you come to fiddle with one of its ctors?), you can sneak in a private base so that it is going to be initialized before the other base, which can then be initialized with the private base's already calculated values:
class my_dirty_little_secret {
// friend class the_class;
public:
my_dirty_little_secret(const std::string& str)
{
// however that calculates x, y, and z from str I wouldn't know
}
int x;
std::string y;
float z;
};
class the_class : private my_dirty_little_secret // must be first, see ctor
, public the_other_base_class {
public:
the_class(const std::string str)
: my_dirty_little_secret(str)
, the_other_base_class(x, y, z)
{
}
// ...
};
The my_dirty_little_secret class is a private base so that users of the_class cannot use it, all of its stuff is private, too, with explicit friendship granting only the_class access to it. However, since it's listed first in the base class list, it will reliably be constructed before the_other_base_class, so whatever it calculates can be used to initialize that.
A nice comment at the base class list hopefully prevents from others breaking things by refactoring.
IMHO I dont think it is possible to defer calling the base class constructor in the way that you mentioned.
Wow, we were all young once. This answer won't work, so don't use it. Content left for historical purposes.
If you have full control over the base class, I'd recommend adding a protected method to do the class initialization, make it virtual, and put the your derived class implementation details in it before it calls its base:
class Base
{
public:
Base()
{
Initialize();
}
protected:
virtual void Initialize()
{
//do initialization;
}
};
class Derived : Base
{
public:
Derived() : Base()
{
}
protected:
virtual void Initialize()
{
//Do my initialization
//call base
Base::Initialize();
}
};
Another option, based on the suggestion from #Konrad is to have a static method to construct the object, e.g.:
class Derived {
public:
Derived(int p1, int p2, int p3) : Base(p1, p2) { }
static Derived* CreateDerived(int p3) { return new Derived(42, 314, p3); }
};
Ive found this useful when extending a class from a library and having multiple parameters to override.
You can even make the constructor private
struct base{
base(int x){}
};
struct derived : base{
derived(int x) : base(x){}
};
This is how base class constructors are invoked in C++ from the initialization list of derived class.