This question already has answers here:
No Matching Function Call to Base class
(4 answers)
Closed 3 years ago.
Consider the following:
# include <iostream>
using namespace std;
class Base{
public:
Base(int a) {
cout << "Base" << endl;
}
};
class Child: public Base{
public:
Child(int a) {
cout << "Child" << endl;
}
};
int main() {
Child c = Child(0);
}
On compilation the error no matching function for call to ‘Base::Base()’ is given. Explicitly declaring a default constructor for Base fixes this issue.
It seems to me that if I want to inherit from a class, then it needs to have a default constructor? Even though (in this example) it never gets called? Is this correct, and if so, why? Otherwise, what's wrong the above code?
No, that is not a correct assumption.
You just have an error. Your derived class constructor must call the one and only Base constructor you provide which is a one parameter constructor.
Child(int a)
: Base(a)
{
cout << "Child" << endl;
}
Related
This question already has answers here:
Difference between calling of virtual function and non virtual function?
(5 answers)
Virtual dispatch implementation details
(3 answers)
Closed 8 months ago.
I googled and learnt the differences between function hiding and function overriding.
I mean I understand the output of testStuff(), which is seen in the below code snippet.
But what confuses me is that a instance of derived class could be assigned to a reference of the base class. And calling the overriding function through the said reference finally invoking the function of the derived class other than the base class.
Could somebody shed some light on this matter?
Here is the code snippet:
#include <iostream>
using namespace std;
class Parent {
public:
void doA() { cout << "doA in Parent" << endl; }
virtual void doB() { cout << "doB in Parent" << endl; }
};
class Child : public Parent {
public:
void doA() { cout << "doA in Child" << endl; }
void doB() { cout << "doB in Child" << endl; }
};
void testStuff() { //I can understand this function well.
Parent* p1 = new Parent();
Parent* p2 = new Child();
Child* cp = new Child();
p1->doA();
p2->doA();
cp->doA();
p1->doB();
p2->doB();
cp->doB();
}
int main()
{
Child cld;
Parent prt = cld;
Parent &ref_prt = cld;
prt.doA();
ref_prt.doA();
prt.doB();
ref_prt.doB(); //The one which most surprised me! I know `Child::doB()` overrides `Parent::doB()`. And I understand the output for `testStuff()`.
//But I still do not understand this line and `Parent &ref_prt=cld`.
return 0;
}
Here is the output:
doA in Parent
doA in Parent
doB in Parent
doB in Child
But what confuses me is that a instance of derived class could be assigned to a reference of the base class. And calling the overriding function through the said reference finally invoking the function of the derived class other than the base class.
It is indeed exactly like that.
If a member function is virtual in a class, then calling it through a pointer-or-reference to that class will result in a dynamic dispatch, so if the actual object is of a derived class which overrides that function (btw, it neededn't declare it virtual because it's already virtual; and it'd better delcare it override, so that it errors out if it doesn't really override, e.g. because you mistyped the name), than that override will be called.
Tha page linked above should sufficient to shed light on this as well as other doubts.
I am implementing the Decorator design pattern in c++ and I ran into this problem (code taken from https://www.studytonight.com/cpp/initializer-list-in-cpp.php):
#include<iostream>
using namespace std;
class Base_
{
public:
// parameterized constructor
Base_(int x)
{
cout << "Base Class Constructor. Value is: " << x << endl;
}
};
class InitilizerList_:public Base_
{
public:
// default constructor
InitilizerList_()
{
Base_ b(10);
cout << "InitilizerList_'s Constructor" << endl;
}
};
int main()
{
InitilizerList_ il;
return 0;
}
As the website states, this doesn't compile because the base constructor gets called before the derived constructor, and this problem is solved using initializer lists. My question is: Can this be implemented without initializer lists and if so, how? Initializer lists were introduced in c++ 11 (I think) so what if you were trying to do this in c++ 98 for example?
The syntax to delegate to the base class constructor from the derived class constructor would be as follows
class InitilizerList_ : public Base_
{
public:
// default constructor
InitilizerList_() : Base_(10)
{
cout << "InitilizerList_'s Constructor" << endl;
}
};
You're getting confused on the terminology. There is an initializer list, which looks like { for, bar, baz, ... }, there is a std::initializer_list type that can wrap an initilizer list, and then there is the class member initialization list, which is used to initialize the members in the class.
That last one is what you want and has been part of C++ since it was created. Using one would give you
InitilizerList_() : Base_(10)
{
cout << "InitilizerList_'s Constructor" << endl;
}
This question already has answers here:
Why won't the C++ compiler disambiguate between an inherited public and an inherited private method with the same name?
(5 answers)
Closed 1 year ago.
In the code below the public method Base2::f() is expected to become a private member of the Derived class however the compiler complains about ambiguity.
The question is on the basic understanding of inheritance. I appreciate if someone can help to shed some light on it.
#include <iostream>
template <typename TDerived>
class Base1 {
public:
void f() { static_cast<TDerived &>(*this)->f_impl(); }
};
class Base2 {
public:
void f() { std::cout << "f()" << std::endl; }
};
class Derived : public Base1<Derived>, private Base2 {
public:
void f_impl() { std::cout << "f_impl()" << std::endl; }
};
int main() {
Derived d;
d.f();
}
Jarod42 rightfully posted the comment
The check of visibility (public/private) is done after the selection,
and so it is ambiguous
Here is a relevant section from cppreference
Member access does not affect visibility: names of private and
privately-inherited members are visible and considered by overload
resolution, implicit conversions to inaccessible base classes are
still considered, etc. Member access check is the last step after any
given language construct is interpreted. The intent of this rule is
that replacing any private with public never alters the behavior of
the program.
This question already has answers here:
private inheritance
(6 answers)
What is the difference between public, private, and protected inheritance in C++?
(16 answers)
Closed 3 years ago.
Why would the following code run into error of ‘A’ is an inaccessible base of ‘B’? Here's my thoughts:
whenever we call function foo(), it will execute new B(5), which will first call the constructor of its base struct A.
struct A's constructor function is a public method, hence it should be accessible by its derived struct B (as protected if i'm not wrong).
then struct B's constructor function will be call to create a vector with five 0s.
then deleting object a will call destructor B, then destructor A.
Is there anything wrong with my logic? Your answer will be greatly appreciated
#include <iostream>
#include <vector>
using namespace std;
struct A
{
A() { cout << "Constructor A called"<< endl;}
virtual ~A() { cout << "Denstructor A called"<< endl;}
};
struct B : private A
{
vector<double> v;
B(int n) : v(n) { cout << "Constructor B called"<< endl;}
~ B() { cout << "Denstructor B called"<< endl;}
};
int main()
{
const A *a = new B(5);
delete a;
return 0;
}
There's nothing wrong with your logic, except that it's missing one point:
private inheritance basically means that only the inheriting class (B in this case) knows that it inherits from the base A.
That in turn means that only B can make use of all the privileges that come with this inheritance. One of these privileges is to be able to cast B* to A*. The function foo() doesn't know about B's inheritance, so it cannot perform that cast.
TL;DR
You are deriving B as 'private' from A. You must change it to
struct B : public A{
vector<double> v;
B(int n): v(n) {std::cout << "B Constructor" << std::endl};
~B() {std::cout << "B Destruktor" << std:.endl;};
};
Extended explanation
By using private inheritance you define B has a A instead of B is a A. With a has-a dependency you cannot up- and downcast between both classes (Apple cannot become a worm and vice versa. Even if an apple has a worm).
You mainly use private inheritance if you want to take advante of features implemented by another class, without exposing the public Inteface of the used class. For e.g. You could use features of a parser inside your class without being a parser on your own.
This question already has answers here:
What is object slicing?
(18 answers)
Closed 8 years ago.
I checked this code, and i saw that by the end of the function func()
the destructor of base class have been called twice.
I dont understand why??
thank you..
class base {
public:
base(){cout << "ctor of base\n";}
~base(){cout << "d-ctor of base\n";}
};
class derived: public base
{
public:
derived(){cout << "ctor of derived\n";}
~derived(){cout << "d-ctor of derived\n";}
};
void func(base ob)
{
cout << "inside func\n";
}
void main()
{
derived ob;
func(ob);
system("pause");
}
Refactoring your base class like this:
class base {
public:
base(){cout << "ctor of base\n";}
base(const base&) {cout << "copy-ctor of base\n";}
~base(){cout << "d-ctor of base\n";}
};
would issue the following output:
ctor of base
ctor of derived
copy-ctor of base
inside func
d-ctor of base
d-ctor of derived
d-ctor of base
Showing pretty clearly your base variable inside func was copied and then destroyed.
base is passed by value to func.
This means a sliced copy of ob will be created.
This will be destroyed as well as ob itself. The destructor of ob (derived::~derived) will automatically call the base classes destructor.
Therefore the base destructor is called two times.
When you call the function you take the parameter by value. Therefore you create a local variable of type base in func.
When you return from func, the local variables are destroyed, so ob's descrutor (which has type base is called.
You have to pass polymorphic types via reference or pointer.
This is called the slicing problem. See this link for details.