Problems understanding base and derived class connection

So i was having this question "What members of a class can be accessed from a class derived from it?"
I thought that it depends on how we use this base class (public , private, protected)
Theoretically i read that :

If a base class is private than protected and private members can be used only by derived classes.
If base class is protected than same thing except that 1st derived class can be used further as base class to other classes.
If base class is public than public member names can be used by all functions. At one place i read that this basically means that derived class basically becomes its base class and u can use derived class in places where base class argument is necessary. But on the other place i read that u still cant access base's private parts.

So i tried to check out what can i actually access in every possible case in practice and turned out that i can't even access protected part constructor from my Base class (class D_public : public Base). I even tried typing using Base::Base; as B.Stroustrup did in his book but still nothing.

Maybe i have to write brand new constructor for all the derived classes? If that's so what's the point of "taking" members from base class if u have to redefine them all over again anyway?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
using namespace std;


class Base{
public:
	int get_x(){ return x; }
protected:
	Base(int num) : x{ num }{}
	virtual void set_x(int num){ x = num; }
private:
	int x;
};

class D_public : public Base{


};

class D_protected : protected Base{

};

class D_private : private Base{

};


int main(){
	D_public pub{ 5 };

	system("pause");
}

Compiler error :
Error 1 error C2440: 'initializing' : cannot convert from 'initializer-list' to 'D_public'
Last edited on
Thanks man, i'm on it
So i made this new version that actually works but this got me thinking isn't there any other way to use abstract class constructor in derived class without doing this
1
2
D_public(int num) : Base(num){}; 
D_public() : Base(){};

Its almost like writing constructor from scratch and if i want to check if the value given is good and throw exception if its not i bet i have to type that in { . . . } as well so my D_public class constructor would look like this
1
2
3
D_public(int num) : Base(num){
    if(num <= 0) throw //something
}; 


In my example i couldn't even use default constructor from base class that is public.
I had to write D_public() : Base(){};

Isn't there any way to write constructor in base class and just forget about it in derived classes?

1 more question - Why would we define private constructor and how could we actually access it from derived class to create object?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
using namespace std;


class Base{
public:
	int get_x(){ return x; }
	Base(){ x = 20; }		        // public default constructor
protected:
	Base(int num) : x{ num }{}		// protected construcor
	virtual void set_x(int num){ x = num; }
private:
	int x;
};

class D_public : public Base{
public:
	D_public(int num) : Base(num){};    // Can i use Base(int) without this????
	D_public() : Base(){};		    // Can i use Base() without this????

};



int main(){
	D_public pub{ 5 };
	D_public pub2;
	cout << "pub.x = " << pub.get_x() << endl;
	cout << "pub2.x = " << pub2.get_x() << endl;

	system("pause");
}


5
20
Last edited on
Can i use Base(int) without this???
What do you mean? If a default constructor (without parameter) is available you don't need to call it explicitly. You can always call something like set_x(...) later. But in this case it makes sense.


Can i use Base() without this????
You can write it like so:
D_public() {} // Note: the explicit call of the default constructor is not necessary
Actually a default constructor that does nothing don't need to appear at all.

1 more question - Why would we define private constructor and how could we actually access it from derived class to create object?
You cannot access a private constructor. That's the trick. E.g.: If want to disallow copying an object you make the copy constructor (and operator=(...)) private. In that case pub = pub2; would cause a compiler error.

It's generally not a good idea to throw in a constructor (due to initialization that might or might not happen. For instance in the derived class). Rather process the error handling later.
Last edited on
I'm sorry i didn't put my thoughts out correct, what i mean with
Can i use Base(int) without this???
and
Can i use Base() without this????

is this.
If i have these 2 constructors in my base class
public : Base(){ x = 20; }
protected : Base(int num) : x{ num }{}
Can i somehow use them in my derived class D_public so i could use my derived class like this
D_public pub; or like this
D_public pub2{5};
and get x to be initialized to 20 in pub and 5 in pub2 without need to include these 2 lines in my class D_public : public Base

line 1 : D_public(int num) : Base(num){};
line 2 : D_public() : Base(){};
You cannot access a private constructor. That's the trick
With constructor delegation, it can also be used as common part of initialization not intended to be used outside of class.

It's generally not a good idea to throw in a constructor (due to initialization that might or might not happen. For instance in the derived class).
I disagree. If class cannot establish its invariants in constructor it should throw. All initializated members/base classes will be automatically destroyed, memory allocated — freed, and program will behave as object was never created in first place.
A default constructor is only generated when no other constructors exists. So yes, you need those two line, but you may simplify line 2: D_public() {}

Why is it such a problem that these lines exists?
You can also inherit costructors from base class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

struct B
{
	B() = default;
	B(int) { std::cout << "Parametrized B constructor\n"; }
};

struct D : B
{
	using B::B;
};

int main()
{
    D a;
    D b(34);
}

MiiNiPaa wrote:
You can also inherit costructors from base class:
Is this allowed in C++14 or so? The C++ shell doesn't allow this.
I can use using B::B; only if constructor in B is public right?
If its protected i have to use D(int num) : B(num){}; right?
Yes, inheriting constructors inherits access specifiers as well, so you need to manually call protected constructor from public one. Also if you explicitely define any constructor in derived class, default constructor will not be inherited.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

struct B
{
	int x = 0;
	B() = default;
	B(int num) : x{num} {}
};

struct D : B
{
	using B::B;
};

int main()
{
	D a;
	D b(34);              //error is coz of this line
	std::cout << a.x << std::endl;
	system("pause");
}


When i try to compile this im getting error
Error 1 error C2664: 'D::D(const D &)' : cannot convert argument 1 from 'int' to 'const D &'
2 IntelliSense: no instance of constructor "D::D" matches the argument list
argument types are: (int)


Why is this happening?
I'm sorry for so many questions
Last edited on
Last edited on
Ohh that must be it, i'm using 2013 version :)
Hey but i'm feeling a lot smarter already, thanks you guys both so much for help and the links you both gave are great!
I feel like in 2 short months i must be ready for "The C++ programming language" :)
Topic archived. No new replies allowed.