Protected constructor on parent and inherited default one not protected - c++

I have a question about default constructor on inherited class when the parent one is protected, in my mind the child class will have a default one protected too, but it's not the case.
Is there's a way to force the default constructor to be protected other than force it on child class ?
C++11 - gcc version 5.3.1 20151219 (Debian 5.3.1-4).
int main ( int argc, char ** argv )
{
using namespace std;
class A
{
public:
static std::shared_ptr<A> CreateInstance ()
{
A * pInstance { new A };
return { pInstance, []( A * pInstance )
{
delete pInstance;
}};
};
protected:
A () = default;
~A () = default;
};
class B : public A
{
};
B b; // It's work !
return 0;
}
Thanks for your help,
WCdr

No, a derived class' automatically-generated default constructor will still be public even if the base class constructor is protected.
There are two ways (I can think of) to prevent derived class B from being directly instantiable:
1. Remove the default constructor in class A
This can be accomplished by providing a constructor that takes a dummy argument:
class A
{
public:
// ...
protected:
A (int) {}
};
class B : public A
{
};
B b; // error: B::B()' is implicitly deleted because the
// default definition would be ill-formed
Instantiating B will fail, because B's automatically-generated default constructor will attempt to use A's default constructor, which does not exist.
But this is easily circumvented:
class B : public A
{
public:
B() : A(0) {}
}
B b; // works
2. Force the derived class' constructor to be protected
class B
{
// ...
protected:
B() = default;
}
Option (2) will be the least surprising to others reading your code, and is the option that I recommend. Anyone familiar with static createFoo factory functions will understand why the constructor is made private or protected.
EDIT
When using static create factory functions in a class hierarchy, the common idiom is for derived classes to also provide static create factory functions, and make their constructor private or protected.
Derived classes should not use the create factory function of the base class. They should invoke base class constructor, either implicitly or explicitly.
class Base
{
public:
static shared_ptr<Base> create()
{
return shared_ptr<Base>(new Base);
}
protected:
Base() {...}
};
class Derived
{
public:
static shared_ptr<Derived> create()
{
return shared_ptr<Derived>(new Derived);
}
protected:
Derived() {...} // Implicitly calls base class default constructor
};
// Usage
auto b = Base::create();
auto d = Derived::create();

Related

call base class function in derived class constructor

I know it's OK to call base class function in a derived class constructor, because base class is constructed before derived class.But I'm not sure if this is a good practice.Example code is:
class Base {
public:
int Get() const { return i_; }
void Set(const int i) { i_ = i; }
private:
int i_{0};
};
class Derived : public Base {
// initialize `derived_i_` with a call to base class function, Is this a good
// practice in production code?
Derived() : derived_i_{Get()} {
// do some other things
}
private:
int derived_i_{0};
};
To be more pedantic, you could write your constructor as the following:
Derived() : Base(), derived_i_{Get()} {
// do some other things
}
The compiler should fully construct the base class before doing any initialization of the derived class.

Why the following C++ program prints '0' instead of '6'?

I've two classes called FWindow and FFramwWindow. The FFramwWindow class inherits the FWindow. The FWindow class contains two constructor method.
The first one is default constructor and the second one contains one parameter of int type.
I call the second constructor from the FFramwWindow class default constructor to initialize a member variable of the FWindow class called 'value'.
But I don't know why it isn't working -
class FWindow {
public:
int value;
FWindow()
{
this->value = 0;
}
FWindow(int val)
{
this->value = val;
}
};
class FFramwWindow : public FWindow
{
public:
FFramwWindow()
{
FWindow::FWindow(6);
printf("value %d\n", this->value);
}
};
int main(int argc, _TCHAR* argv[])
{
FFramwWindow obj;
return 0;
}
The above code prints - value 0
Where I expected it will print - value 6
Seems it's only calling the default base class constructor, not the second one that I called explicitly.
Note: I'm using Visual Studio 2008
Because you should do the following in constructor:
FFramwWindow() : FWindow(6)
{
....
In your original code you create a local (in constructor scope) object of FWindow.
the code
FWindow::FWindow(6);
is not a call to the parent constructor, but the creation of a local instance of FWindow. The correct syntax in C++ to specify which FWindow constructor should be called is
FFramwWindow() : FWindow(6)
{
...
}
If you do not specify the constructor to use for the base class (and for data members), C++ uses the default constructor, that is
FFramwWindow()
{
...
}
is equivalent to
FFramwWindow() : FWindow()
{
...
}
Note that if you have multiple inheritance you should constructors for each base class separating them with comma. As bonus information, the base constructors are called in the order specified in the inheritance definition, not those in which you specify them in the constructor:
class A {
A();
A(int n);
A(string s);
};
class B {
B(int n = 6);
}
class C {
C();
C(float x);
}
class D: public A, public B, public C {
D();
}
D::D() : C(3),A(5)
{
}
In this example, creating an instance of D will invoke in order the constructors for A(5), B(6), C(3.0), D()
You must call the constructor function of the base class when you declare the derived class's constructor. Consider this example:
#include<iostream>
class base
{
public:
int i;
base()
{
i = 0;
}
base(int p)
{
i = p;
}
};
class derived1: public base
{
public:
derived1():base()
{
std::cout<<i<<std::endl; //i is 0 here
}
};
class derived2: public base
{
public:
derived2():base(10)
{
std::cout<<i<<std::endl; //i is 10 here
}
};
class derived3: public base
{
public:
derived3(int x):base(x)
{
std::cout<<i<<std::endl;
//this takes an argument from the derived class's constructor
//as base class's constructor's parameter
}
};
int main()
{
derived1 d1;
derived2 d2;
derived3 d3(9);
return 0;
}
In derived1 class, the first constructor of the base class is called. In derived2 class, the second constructor is called. And in third case, the constructor function takes an argument which is passed to the base class's constructor (That means we are using the second constructor of base class).
In your code,You didn't call the base class's constructor which by default calls the constructor that takes no argument. That's why it is outputting 0.
FWindow::FWindow(6);
This statement just creates a temporary new object of class FWindow which is destroyed right after this statement is executed. Constructor functions are meant to be called automatically when you create a object. They are not meant to be called manually.
You can find some explanation here: http://www.geeksforgeeks.org/possible-call-constructor-destructor-explicitly/

The constructor function in a pure virtual class should be "protected" or "public"?

The following example is from the book "Inside C++ object model"
class Abstract_base {
public:
virtual ~Abstract_base () = 0;
virtual void interface () const = 0;
virtual const char* mumble () const
{
return _mumble;
}
protected:
char *_mumble;
};
The author says if I want to initialize _mumble, the data member of the pure virtual base class, a "protected constructor" should be implemented.
But why protected? And why "public constructor" is not suitable for this class?
Thanks for your answers, and it would be perfect if there's an example.
It doesn't really matter, since you're not allowed to construct objects of the base class anyway. Making it protected serves only as a reminder of the fact that the class is supposed to be a base class; it's only cosmetics/documentation.
Consider
struct Base {
virtual ~Base() = 0;
protected:
Base() { std::puts("Base constructor"); }
};
Base::~Base() { std::puts("Base destructor"); }
struct Derived : Base {};
int main()
{
//Base b; // compiler error
Derived d;
Base *b = new Derived();
delete b;
}
Removing the protected doesn't change the meaning of the program in any way.
Abstract classes and construction of such
It doesn't matter if the constructor is public or protected, since an abstract class cannot be instantiated.
You must inherit from it in order to have it's constructor called, and since the Derived class calls the constructor of the abstract class it doesn't matter what protection level you choose, as long as the Derived class can access it.
One reason that one could possibly have for making it protected is to serve as a reminder that the class must be constructed through inheritance, but honestly that should be clear enough when seeing that it has pure virtual member-functions.
example snippet
struct B {
virtual void func () = 0;
virtual ~B () = 0 { };
};
B::~B () { }
struct D : B {
void func () override;
};
int main () {
B b; // will error, no matter if Bs ctor is 'public' or 'protected'
// due to pure virtual member-function
D d; // legal, D has overriden `void B::func ()`
}
A pure virtual class cannot be instantiated, so it doesn't make a difference if the constructor is public or protected.
A public constructor is syntactically correct. However, making it protected will carry a stronger indication that the class cannot be instantiated.
For an example: http://ideone.com/L66Prq
#include <iostream>
using namespace std;
class PublicAbstract {
public:
PublicAbstract() { }
virtual void doThings() =0;
};
class ProtectedAbstract {
protected:
ProtectedAbstract() { }
public:
virtual void doMoreThings() =0;
};
class B: public PublicAbstract {
public:
void doThings() { }
};
class C: public ProtectedAbstract {
public:
void doMoreThings() { }
};
int main() {
B b;
C c;
return 0;
}
A public constructor would not be very useful, since abstract classes cannot be instantiated in the first place.
A protected constructor makes sense: this way, a derived concrete class can provide its own public constructor that chains to the protected constructor of the base abstract class.
Protecetd ctor will make sure the ctor gets called by only the classes which derive from Abstract_base.
Public ctor is not suitable because the class contains a pure virtual method! How are you planning to instantiate a pure-virtual class if not via its child classes?

C++: How to enforce derived class to set base member variables?

I have a base class with a member variable (preferably private) and I need to enforce derived classes to initialize it with a value based on their implementation; much like a pure virtual function.
To clarify, I want to declare a member in Base, have derived classes initialize it, and if they don't they get a compiler error. In the following code, I declared default constructor of Base to be protected. Then declared default constructor of Derived to be private.
class Base {
private:
int _size;
protected:
Base(){}
/* pure virtual methods */
public:
Base(int size) : _size(size){} // must enforce derived to call this.
virtual ~Base(){}
/* more pure virtual methods */
};
class Derived : public Base {
private:
Derived() {}
public:
Derived(int size) : Base(size) {
//Base::Base(size);
}
};
int main()
{
Derived* d1 = new Derived(); // throws an error as needed:
// "Cannot access private member declared in class 'Derived'"
Derived* d2 = new Derived; // throws an error as needed:
// "Cannot access private member declared in class 'Derived'"
Derived* d3 = new Derived(5); // works as needed
return 0;
}
The problem with the above code is that if another definition of Derived doesn't hide the default constructor. I'm still stuck with an uninitialized Base::_size.
I don't know if there is another way to go about this other than inheritance, because I still need derived classes to implement their own behavior for several methods declared in Base.
Any pointers are appreciated.
After the confusion about calling a base class ctor and default ctors, maybe the solution is just to not have a default ctor in Base?
class Base {
private:
int _size;
public:
// no default ctor
Base(int size) : _size(size) {} // must enforce derived to call this.
virtual ~Base(){}
/* more pure virtual methods */
};
class Derived : public Base {
public:
// no default ctor
Derived(int size) : Base(size){
}
// examplary default ctor:
//Derived() : Base(42) {}
};
int main()
{
Derived d1; // error: no default ctor
Derived* d2 = new Derived; // same, but why use the free store?
Derived d3(5); // works as needed
Derived* d4 = new Derived(5); // same, but why use the free store?
return 0;
}
To be explicit about not having a default ctor, one could use
class Base {
/* ... */
Base() = delete;
/* ... */
};
Use a constructor
class Base1 {
protected:
Base1(int forward) {
thingYouWantToHide = forward;
}
private:
int thingYouWantToHide;
};
class Derived1: public Base1 {
public:
Derived1(): Base1(5) {}
};
class Base2 {
private:
int value;
protected:
Base2() {
value = calledToGet();
}
virtual int calledToGet() = 0;
virtual ~Base2() {} //shut compiler warnings up
};
class Derived2: public Base2 {
virtual int calledToGet() {
return 5;
}
};
int main(int,char**) {
Derived1 a;
Derived2 b;
return 0;
}
You may think Derived2 will work, but remember Derived2 is not constructed until Base2 is, so that virtual is an undefined reference when Base2 is being constructed.
You should use the first case, type-traits if it is a constant (static const) or fundamental to the type.

Does C++ require you to initialize base class members from its derived class?

class Base {
public:
int a;
Base():a(0) {}
virtual ~Base();
}
class Derived : public Base {
public:
int b;
Derived():b(0) {
Base* pBase = static_cast<Base*>(this);
pBase->Base();
}
~Derived();
}
Is the call to the base class constructor necessary or does c++ do this automatically? e.g.
Does C++ require you to initialize base class members from any derived class?
The base class's constructor will automatically be called before the derived class's constructor is called.
You can explicitly specify which base constructor to call (if it has multiple) using initialization lists:
class Base {
public:
int a;
Base():a(0) {}
Base(int a):a(a) {}
};
class Derived {
public:
int b;
Derived():Base(),b(0) {}
Derived(int a):Base(a),b(0) {}
};
Base class constructors are called automatically (and before derived class contructors). So you need not, and must not, try to call base constructors manually.